diff options
1092 files changed, 31054 insertions, 11107 deletions
diff --git a/AUTHORS.md b/AUTHORS.md index 752300cb5b..a5ef24e825 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -70,12 +70,14 @@ name is available. Joshua Grams (JoshuaGrams) Juan Linietsky (reduz) Julian Murgia (StraToN) + Justo Delgado (mrcdk) Kostadin Damyanov (Max-Might) Leon Krause (eska014) Marc Gilleron (Zylann) Marcelo Fernandez (marcelofg55) Mariano Javier Suligoy (MarianoGnu) Mario Schlack (hurikhan) + Martin Sjursen (binbitten) Masoud BH (masoudbh3) Matthias Hölzl (hoelzl) Max Hilbrunner (mhilbrunner) @@ -85,8 +87,10 @@ name is available. Ovnuniarchos Patrick (firefly2442) Paul Batty (Paulb23) + Paul Joannon (paulloz) Pawel Kowal (pkowal1982) Pedro J. Estébanez (RandomShaper) + Pieter-Jan Briers (PJB3005) Poommetee Ketson (Noshyaar) PrzemysÅ‚aw GoÅ‚Ä…b (n-pigeon) Ralf Hölzemer (rollenrolm) @@ -113,7 +117,8 @@ name is available. m4nu3lf marynate mrezai - rraallvv + robfram romulox-x + rraallvv sersoong yg2f (SuperUserNameMan) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..533968886e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,140 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). + +## [3.0] - 2018-01-29 + +### Added + +- Physically-based renderer using OpenGL ES 3.0. + - Uses the Disney PBR model, with clearcoat, sheen and anisotropy parameters available. + - Uses a forward renderer, supporting multi-sample anti-aliasing (MSAA). + - Parallax occlusion mapping. + - Reflection probes. + - Screen-space reflections. + - Real-time global illumination using voxel cone tracing (GIProbe). + - Proximity fade and distance fade (useful for creating soft particles and various effects). + - [Lightmapper](https://godotengine.org/article/introducing-new-last-minute-lightmapper) for lower-end desktop and mobile platforms, as an alternative to GIProbe. +- New SpatialMaterial resource, replacing FixedMaterial. + - Multiple passes can now be specified (with an optional "grow" property), allowing for effects such as cel shading. +- Brand new 3D post-processing system. + - Depth of field (near and far). + - Fog, supporting light transmittance, sun-oriented fog, depth fog and height fog. + - Tonemapping and Auto-exposure. + - Screen-space ambient occlusion. + - Multi-stage glow and bloom, supporting optional bicubic upscaling for better quality. + - Color grading and various adjustments. +- Rewritten audio engine from scratch. + - Supports audio routing with arbitrary number of channels, including Area-based audio redirection ([video](https://youtu.be/K2XOBaJ5OQ0)). + - More than a dozen of audio effects included. +- Rewritten 3D physics using [Bullet](http://bulletphysics.org/). +- UDP-based high-level networking API using [ENet](http://enet.bespin.org/). +- IPv6 support for all of the engine's networking APIs. +- Visual scripting. +- Rewritten import system. + - Assets are now referenced with their source files, then imported in a transparent manner by the engine. + - Imported assets are now cached in a `.import` directory, making distribution and versioning easier. + - Support for ETC2 compression. + - Support for uncompressed Targa (.tga) textures, allowing for faster importing. +- Rewritten export system. + - GPU-based texture compression can now be tweaked per-target. + - Support for exporting resource packs to build DLC / content addons. +- Improved GDScript. + - Pattern matching using the `match` keyword. + - `$` shorthand for `get_node()`. + - Setters and getters for node properties. + - Underscores in number literals are now allowed for improved readability (for example,`1_000_000`). + - Improved performance (+20% to +40%, based on various benchmarks). +- [Feature tags](http://docs.godotengine.org/en/latest/learning/workflow/export/feature_tags.html) in the Project Settings, for custom per-platform settings. +- Full support for the [glTF 2.0](https://www.khronos.org/gltf/) 3D interchange format. +- Freelook and fly navigation to the 3D editor. +- Built-in editor logging (logging standard output to a file), disabled by default. +- Improved, more intuitive file chooser in the editor. +- Smoothed out 3D editor zooming, panning and movement. +- Toggleable rendering information box in the 3D editor viewport. + - FPS display can also be enabled in the editor viewport. +- Ability to render the 3D editor viewport at half resolution to achieve better performance. +- GDNative for binding languages like C++ to Godot as dynamic libraries. + - Community bindings for [D](https://github.com/GodotNativeTools/godot-d), [Nim](https://github.com/pragmagic/godot-nim) and [Python](https://github.com/touilleMan/godot-python) are available. +- Editor settings and export templates are now versioned, making it easier to use several Godot versions on the same system. +- Optional soft shadows for 2D rendering. +- HDR sky support. +- Ability to toggle V-Sync while the project is running. +- Panorama sky support (sphere maps). +- Support for WebM videos (VP8/VP9 with Vorbis/Opus). +- Exporting to HTML5 using WebAssembly. +- C# support using Mono. + - The Mono module is disabled by default, and needs to be compiled in at build-time. + - The latest Mono version (5.4) can be used, fully supporting C# 7.0. +- Support for rasterizing SVG to images on-the-fly, using the nanosvg library. + - Editor icons are now in SVG format, making them better-looking at non-integer scales. + - Due to the library used, only simpler SVGs are well-supported, more complex SVGs may not render correctly. +- Support for oversampling DynamicFonts, keeping them sharp when scaled to high resolutions. +- Improved StyleBoxFlat. + - Border widths can now be set per-corner. + - Support for anti-aliased rounded and beveled corners. + - Support for soft drop shadows. +- VeryLoDPI (75%) and MiDPI (150%) scaling modes for the editor. +- Improved internationalization support for projects. + - Language changes are now effective without reloading the current scene. +- Implemented missing features in the HTML5 platform. + - Cursor style changes. + - Cursor capturing and hiding. +- Improved styling and presentation of HTML5 exports. + - A spinner is now displayed during loading. +- Rewritten the 2D and 3D particle systems. + - Particles are now GPU-based, allowing their use in much higher quantities than before. + - Meshes can now be used as particles. + - Particles can now be emitted from a mesh's shape. + - Properties can now be modified over time using an editable curve. + - Custom particle shaders can now be used. +- New editor theme, with customizable base color, highlight color and contrast. + - A light editor theme option is now available, with icons suited to light backgrounds. + - Alternative dark gray and Arc colors are available out of the box. +- New adaptive text editor theme, adjusting automatically based on the editor colors. +- Support for macOS trackpad gestures in the editor. +- Exporting to macOS now creates a `.dmg` disk image if exporting from an editor running on macOS. + - Signing the macOS export now is possible if running macOS (requires a valid code signing certificate). +- Exporting to Windows now changes the exported project's icon using `rcedit` (requires WINE if exporting from Linux or macOS). +- Improved build system. + - Support for compiling using Visual Studio 2017. + - [SCons](http://scons.org/) 3.0 and Python 3 are now supported (SCons 2.5 and Python 2.7 still work). + - Link-time optimization can now be enabled by passing `use_lto=yes` to the SCons command line. + - Produces faster and sometimes smaller binaries. + - Currently only supported with GCC and MSVC. + - Added a progress percentage when compiling Godot. + - `.zip` archives are automatically created when compiling HTML5 export templates. +- Easier and more powerful way to create editor plugins with EditorPlugin and related APIs. + +### Changed + +- Increased the default low-processor-usage mode FPS limit (60 → 125). + - This makes the editor smoother and more responsive. +- Increased the default 3D editor camera's field of view (55 → 70). +- Increased the default 3D Camera node's field of view (65 → 70). +- Changed the default editor font (Droid Sans → [Noto Sans](https://www.google.com/get/noto/)). +- Changed the default script editor font (Source Code Pro → [Hack](http://sourcefoundry.org/hack/)) +- Renamed `engine.cfg` to `project.godot`. + - This allows users to open a project by double-clicking the file if Godot is associated to `.godot` files. +- Some methods from the `OS` singleton were moved to the new `Engine` singleton. +- Switched from [GLEW](http://glew.sourceforge.net/) to [GLAD](http://glad.dav1d.de/) for OpenGL wrapping. +- Changed the SCons build flag for simple logs (`colored=yes` → `verbose=no`). +- The HTML5 platform now uses WebGL 2.0 (instead of 1.0). +- Redesigned the Godot logo to be more legible at small sizes. + +### Deprecated + +- `opacity` and `self_opacity` are replaced by `modulate` and `self_modulate` in all 2D nodes, allowing for full color changes in addition to opacity changes. + +### Removed + +- Skybox support. + - Replaced with panorama skies, which are easier to import. +- Opus audio codec support. + - This is due to the way the new audio engine is designed. +- HTML5 export using asm.js. + - Only WebAssembly is supported now, since all browsers supporting WebGL 2.0 also support WebAssembly. + +[3.0]: https://github.com/godotengine/godot/compare/2.1-stable...3.0-stable @@ -18,6 +18,7 @@ generous deed immortalized in the next stable release of Godot Engine. Gamblify <https://www.gamblify.com> GameDev.TV <https://www.gamedev.tv> + Skirmish <https://skirmish.io> ## Mini sponsors @@ -26,16 +27,19 @@ generous deed immortalized in the next stable release of Godot Engine. Christian Uldall Pedersen Christopher Igoe Christoph Woinke + codetrotter E Hewert Hein-Pieter van Braam + Igors Vaitkus Jamal Alyafei Jay Sistar - Jordan M Lucas Matthieu Huvé + Mike King Nathan Warden Neal Gompa (Conan Kudo) Pascal Julien Ruslan Mustakov + Sébastien Manin Slobodan Milnovic Stephan Lanfermann Stoney Meyerhoeffer @@ -48,6 +52,7 @@ generous deed immortalized in the next stable release of Godot Engine. Asdf cheese65536 Jake Bo + Kris Michael Manuele Finocchiaro Officine Pixel S.n.c. Rémi Verschelde @@ -58,11 +63,17 @@ generous deed immortalized in the next stable release of Godot Engine. Austen McRae Benjamin Botwin Bernhard Liebl + Catalin Moldovan + DeepSquid + Florian Breisch + Gary Oberbrunner Johannes Wuensch Josep G. Camarasa - Kris Michael + Joshua Lesperance Libre-Dépanne + Matthew Bennett Ranoller + Rob Messick Svenne Krap Timothy Hagberg @@ -77,54 +88,64 @@ generous deed immortalized in the next stable release of Godot Engine. Garrett Dockins Guilherme Felipe de C. G. da Silva Harman Bains + John + Justo Delgado Baudà Karsten Bock Laurence Bannister + Rami Robert Willes Robin Arys + Rufus Sasparilla ScottMakesGames Testus Maximus Thomas Bjarnelöf + Wojciech Chojnacki Xavier Tan Zaq Poi + Alessandra Pereyra + Alexey Dyadchenko Amanda Haldy - Andreas Haas - Arnaud Verstuyf Chris Brown Chris Wilson Cody Parker D Daniel Eliasinski Eric Monson - Ezra Theunissen flesk François Cantin + G Barnes GGGames.org Heath Hayes Jeppe Zapp Jeremi Biernacki joe513 + John O'Mahoney + Jordan M Lucas Juraj Móza Justin Arnold - Justo Delgado Baudà Leandro Voltolino Lisandro Lorea + Marco Andrew Cafolla Markus Wiesner + Marvin Nick Nikitin Pablo Cholaky - Paolo Munoz Patrick Schnorbus Pete Goodwin - Rami - Ryan Estes + Phyronnaz + Simon De Greve + Sofox Ted Travis Womack Trent McPheron + Vladimir ## Silver donors 1D_Inc Adam Carr + Adam Smeltzer Alder Stefano Alessandro Senese Ãlvaro DomÃnguez López @@ -133,6 +154,7 @@ generous deed immortalized in the next stable release of Godot Engine. Anthony Bongiovanni Arda Erol Arthur S. Muszynski + Aubrey Falconer Avencherus Bastian Böhm Benedikt @@ -143,6 +165,7 @@ generous deed immortalized in the next stable release of Godot Engine. Bryan Stevenson Carwyn Edwards Casey Foote + Chris Chapin Christian Baune Christian Winter Collin Shooltz @@ -150,27 +173,33 @@ generous deed immortalized in the next stable release of Godot Engine. Daniel Kaplan Daniel Langegger Daniel Mircea + David David Cravens David May - Diego Moreira Guimarães Dominik Wetzel Eric Martini Fabian Becker fengjiongmax Francesco Lisi - Fredy Romero Sam + Frédéric Alix G3Dev sà rl Geequlim Gerrit Großkopf + Gerrit Procee Gilberto K. Otubo Guldoman - HeartBeast Heribert Hirth + hubert jenkins Hunter Jones + ialex32x + Ivan Vodopiviz Jaime Ruiz-Borau Vizárraga - Jed Rose + Jed Jeff Hungerford + Joel Fivat + Johan Lindberg Jonas Yamazaki + Jonathan Martin Jonathan Nieto Jonathon Josh 'Cheeseness' Bush @@ -178,23 +207,25 @@ generous deed immortalized in the next stable release of Godot Engine. Judd JuDelCo Julian Murgia + Justin Luk KC Chan Kevin Boyer Kevin Kamper Meejach Petersen Klavdij Voncina Lars pfeffer Linus Lind Lundgren + Macil magodev Martin Eigel - Martin Novák Matthew Fitzpatrick Matthias Hölzl - Maurice Meysel Max R.R. Collada memoryruins mhilbrunner Michael Dürwald Michael Gringauz + Michael Labbe + Mikael Olsson MoM monokrome Moritz Laass @@ -203,6 +234,7 @@ generous deed immortalized in the next stable release of Godot Engine. Niclas Eriksen Nik Lee Niko Leopold + nivardus Noi Sek Oleg Tyshchenko Pablo Seibelt @@ -216,19 +248,25 @@ generous deed immortalized in the next stable release of Godot Engine. Pietro Vertechi Piotr Kaczmarski Richman Stewart - Rodolfo Baeza Roger Burgess Roger Smith Roman Tinkov + Ryan Whited Sasori Olkof Scott D. Yelich Sootstone - Stephen Traskal Theo Cranmore + Thibault Barbaroux Thomas Bell Thomas Herzog & Xananax + Thomas Kurz Tom Larrow + Tyler Stafos UltyX + Victor Gonzalez Fernandez + Victor Holt + Viktor Ferenczi + werner mendizabal Wout Standaert Yu He @@ -26,7 +26,7 @@ Before being open sourced in February 2014, Godot had been developed by Juan Linietsky and Ariel Manzur (both still maintaining the project) for several years as an in-house engine, used to publish several work-for-hire titles. -![Screenshot of a 3D scene in Godot Engine](http://download.tuxfamily.org/godotengine/media/screenshots/editor_3d_fracteed.jpg) +![Screenshot of a 3D scene in Godot Engine](https://download.tuxfamily.org/godotengine/media/screenshots/editor_3d_fracteed.jpg) ### Getting the engine diff --git a/SConstruct b/SConstruct index 14f576c595..63105bfa84 100644 --- a/SConstruct +++ b/SConstruct @@ -62,11 +62,11 @@ custom_tools = ['default'] platform_arg = ARGUMENTS.get("platform", ARGUMENTS.get("p", False)) -if (os.name == "posix"): - pass -elif (os.name == "nt"): - if (os.getenv("VCINSTALLDIR") == None or platform_arg == "android" or platform_arg == "javascript"): - custom_tools = ['mingw'] +if os.name == "nt" and (platform_arg == "android" or ARGUMENTS.get("use_mingw", False)): + custom_tools = ['mingw'] +elif platform_arg == 'javascript': + # Use generic POSIX build toolchain for Emscripten. + custom_tools = ['cc', 'c++', 'ar', 'link', 'textfile', 'zip'] env_base = Environment(tools=custom_tools) if 'TERM' in os.environ: @@ -92,6 +92,7 @@ env_base.use_ptrcall = False env_base.split_drivers = False env_base.split_modules = False env_base.module_version_string = "" +env_base.msvc = False # To decide whether to rebuild a file, use the MD5 sum only if the timestamp has changed. # http://scons.org/doc/production/HTML/scons-user/ch06.html#idm139837621851792 @@ -240,14 +241,13 @@ sys.modules.pop('detect') """ if (env_base['target'] == 'debug'): - env_base.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC']) - env_base.Append(CPPFLAGS=['-DSCI_NAMESPACE']) + env_base.Append(CPPDEFINES=['DEBUG_MEMORY_ALLOC', 'SCI_NAMESPACE']) if (env_base['no_editor_splash']): - env_base.Append(CPPFLAGS=['-DNO_EDITOR_SPLASH']) + env_base.Append(CPPDEFINES=['NO_EDITOR_SPLASH']) if not env_base['deprecated']: - env_base.Append(CPPFLAGS=['-DDISABLE_DEPRECATED']) + env_base.Append(CPPDEFINES=['DISABLE_DEPRECATED']) env_base.platforms = {} @@ -329,9 +329,7 @@ if selected_platform in platform_list: if (env["warnings"] == 'yes'): print("WARNING: warnings=yes is deprecated; assuming warnings=all") - env.msvc = 0 - if (os.name == "nt" and os.getenv("VCINSTALLDIR") and (platform_arg == "windows" or platform_arg == "uwp")): # MSVC, needs to stand out of course - env.msvc = 1 + if env.msvc: disable_nonessential_warnings = ['/wd4267', '/wd4244', '/wd4305', '/wd4800'] # Truncations, narrowing conversions... if (env["warnings"] == 'extra'): env.Append(CCFLAGS=['/Wall']) # Implies /W4 @@ -353,7 +351,7 @@ if selected_platform in platform_list: env.Append(CCFLAGS=['-Wall', '-Wno-unused']) else: # 'no' env.Append(CCFLAGS=['-w']) - + env.Append(CCFLAGS=['-Werror=return-type']) #env['platform_libsuffix'] = env['LIBSUFFIX'] suffix = "." + selected_platform @@ -363,7 +361,7 @@ if selected_platform in platform_list: print("Tools can only be built with targets 'debug' and 'release_debug'.") sys.exit(255) suffix += ".opt" - env.Append(CCFLAGS=['-DNDEBUG']) + env.Append(CPPDEFINES=['NDEBUG']) elif (env["target"] == "release_debug"): if env["tools"]: @@ -420,31 +418,32 @@ if selected_platform in platform_list: env["SHLIBSUFFIX"] = suffix + env["SHLIBSUFFIX"] if (env.use_ptrcall): - env.Append(CPPFLAGS=['-DPTRCALL_ENABLED']) + env.Append(CPPDEFINES=['PTRCALL_ENABLED']) # to test 64 bits compiltion # env.Append(CPPFLAGS=['-m64']) if env['tools']: - env.Append(CPPFLAGS=['-DTOOLS_ENABLED']) + env.Append(CPPDEFINES=['TOOLS_ENABLED']) if env['disable_3d']: - env.Append(CPPFLAGS=['-D_3D_DISABLED']) + env.Append(CPPDEFINES=['_3D_DISABLED']) if env['gdscript']: - env.Append(CPPFLAGS=['-DGDSCRIPT_ENABLED']) + env.Append(CPPDEFINES=['GDSCRIPT_ENABLED']) if env['disable_advanced_gui']: - env.Append(CPPFLAGS=['-DADVANCED_GUI_DISABLED']) + env.Append(CPPDEFINES=['ADVANCED_GUI_DISABLED']) if env['minizip']: - env.Append(CPPFLAGS=['-DMINIZIP_ENABLED']) + env.Append(CPPDEFINES=['MINIZIP_ENABLED']) if env['xml']: - env.Append(CPPFLAGS=['-DXML_ENABLED']) + env.Append(CPPDEFINES=['XML_ENABLED']) if not env['verbose']: methods.no_verbose(sys, env) if (not env["platform"] == "server"): # FIXME: detect GLES3 - env.Append( BUILDERS = { 'GLES3_GLSL' : env.Builder(action = methods.build_gles3_headers, suffix = 'glsl.gen.h',src_suffix = '.glsl') } ) + env.Append( BUILDERS = { 'GLES3_GLSL' : env.Builder(action = methods.build_gles3_headers, suffix = 'glsl.gen.h', src_suffix = '.glsl') } ) + env.Append( BUILDERS = { 'GLES2_GLSL' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.gen.h', src_suffix = '.glsl') } ) scons_cache_path = os.environ.get("SCONS_CACHE") if scons_cache_path != None: @@ -478,10 +477,7 @@ if selected_platform in platform_list: if ("check_c_headers" in env): for header in env["check_c_headers"]: if (conf.CheckCHeader(header[0])): - if (env.msvc): - env.Append(CCFLAGS=['/D' + header[1]]) - else: - env.Append(CCFLAGS=['-D' + header[1]]) + env.AppendUnique(CPPDEFINES=[header[1]]) else: @@ -492,127 +488,118 @@ else: print("\nPlease run scons again with argument: platform=<string>") -screen = sys.stdout -node_count = 0 -node_count_max = 0 -node_count_interval = 1 -node_pruning = 8 # Number of nodes to process before prunning the cache -if ('env' in locals()): +# The following only makes sense when the env is defined, and assumes it is +if 'env' in locals(): + screen = sys.stdout + # Progress reporting is not available in non-TTY environments since it + # messes with the output (for example, when writing to a file) + show_progress = (env['progress'] and sys.stdout.isatty()) + node_count = 0 + node_count_max = 0 + node_count_interval = 1 node_count_fname = str(env.Dir('#')) + '/.scons_node_count' -# Progress reporting is not available in non-TTY environments since it -# messes with the output (for example, when writing to a file) -if sys.stdout.isatty(): - show_progress = env['progress'] -else: - show_progress = False - -import time, math - -class cache_progress: - # The default is 1 GB cache and 12 hours half life - def __init__(self, path = None, limit = 1073741824, half_life = 43200): - global node_pruning - self.path = path - self.limit = limit - self.exponent_scale = math.log(2) / half_life - if env['verbose'] and path != None: - screen.write('Current cache limit is ' + self.convert_size(limit) + ' (used: ' + self.convert_size(self.get_size(path)) + ')\n') - self.pruning = node_pruning - self.delete(self.file_list()) - - def __call__(self, node, *args, **kw): - global node_count, node_count_max, node_count_interval, node_count_fname, node_pruning, show_progress - if show_progress: - # Print the progress percentage - node_count += node_count_interval - if (node_count_max > 0 and node_count <= node_count_max): - screen.write('\r[%3d%%] ' % (node_count * 100 / node_count_max)) - screen.flush() - elif (node_count_max > 0 and node_count > node_count_max): - screen.write('\r[100%] ') - screen.flush() - else: - screen.write('\r[Initial build] ') - screen.flush() - # Prune if the number of nodes processed is 'node_pruning' or bigger - self.pruning -= node_count_interval - if self.pruning <= 0: - self.pruning = node_pruning + + import time, math + + class cache_progress: + # The default is 1 GB cache and 12 hours half life + def __init__(self, path = None, limit = 1073741824, half_life = 43200): + self.path = path + self.limit = limit + self.exponent_scale = math.log(2) / half_life + if env['verbose'] and path != None: + screen.write('Current cache limit is ' + self.convert_size(limit) + ' (used: ' + self.convert_size(self.get_size(path)) + ')\n') self.delete(self.file_list()) - def delete(self, files): - if len(files) == 0: - return - if env['verbose']: - # Utter something - screen.write('\rPurging %d %s from cache...\n' % (len(files), len(files) > 1 and 'files' or 'file')) - map(os.remove, files) - - def file_list(self): - if self.path == None: - # Nothing to do - return [] - # Gather a list of (filename, (size, atime)) within the - # cache directory - file_stat = [(x, os.stat(x)[6:8]) for x in glob.glob(os.path.join(self.path, '*', '*'))] - if file_stat == []: - # Nothing to do - return [] - # Weight the cache files by size (assumed to be roughly - # proportional to the recompilation time) times an exponential - # decay since the ctime, and return a list with the entries - # (filename, size, weight). - current_time = time.time() - file_stat = [(x[0], x[1][0], (current_time - x[1][1])) for x in file_stat] - # Sort by the most resently accessed files (most sensible to keep) first - file_stat.sort(key=lambda x: x[2]) - # Search for the first entry where the storage limit is - # reached - sum, mark = 0, None - for i,x in enumerate(file_stat): - sum += x[1] - if sum > self.limit: - mark = i - break - if mark == None: - return [] - else: - return [x[0] for x in file_stat[mark:]] - - def convert_size(self, size_bytes): - if size_bytes == 0: - return "0 bytes" - size_name = ("bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") - i = int(math.floor(math.log(size_bytes, 1024))) - p = math.pow(1024, i) - s = round(size_bytes / p, 2) - return "%s %s" % (int(s) if i == 0 else s, size_name[i]) - - def get_size(self, start_path = '.'): - total_size = 0 - for dirpath, dirnames, filenames in os.walk(start_path): - for f in filenames: - fp = os.path.join(dirpath, f) - total_size += os.path.getsize(fp) - return total_size - -def progress_finish(target, source, env): - global node_count, progressor - with open(node_count_fname, 'w') as f: - f.write('%d\n' % node_count) - progressor.delete(progressor.file_list()) - -try: - with open(node_count_fname) as f: - node_count_max = int(f.readline()) -except: - pass -cache_directory = os.environ.get("SCONS_CACHE") -# Simple cache pruning, attached to SCons' progress callback. Trim the -# cache directory to a size not larger than cache_limit. -cache_limit = float(os.getenv("SCONS_CACHE_LIMIT", 1024)) * 1024 * 1024 -progressor = cache_progress(cache_directory, cache_limit) -Progress(progressor, interval = node_count_interval) - -progress_finish_command = Command('progress_finish', [], progress_finish) -AlwaysBuild(progress_finish_command) + def __call__(self, node, *args, **kw): + global node_count, node_count_max, node_count_interval, node_count_fname, show_progress + if show_progress: + # Print the progress percentage + node_count += node_count_interval + if (node_count_max > 0 and node_count <= node_count_max): + screen.write('\r[%3d%%] ' % (node_count * 100 / node_count_max)) + screen.flush() + elif (node_count_max > 0 and node_count > node_count_max): + screen.write('\r[100%] ') + screen.flush() + else: + screen.write('\r[Initial build] ') + screen.flush() + + def delete(self, files): + if len(files) == 0: + return + if env['verbose']: + # Utter something + screen.write('\rPurging %d %s from cache...\n' % (len(files), len(files) > 1 and 'files' or 'file')) + [os.remove(f) for f in files] + + def file_list(self): + if self.path == None: + # Nothing to do + return [] + # Gather a list of (filename, (size, atime)) within the + # cache directory + file_stat = [(x, os.stat(x)[6:8]) for x in glob.glob(os.path.join(self.path, '*', '*'))] + if file_stat == []: + # Nothing to do + return [] + # Weight the cache files by size (assumed to be roughly + # proportional to the recompilation time) times an exponential + # decay since the ctime, and return a list with the entries + # (filename, size, weight). + current_time = time.time() + file_stat = [(x[0], x[1][0], (current_time - x[1][1])) for x in file_stat] + # Sort by the most resently accessed files (most sensible to keep) first + file_stat.sort(key=lambda x: x[2]) + # Search for the first entry where the storage limit is + # reached + sum, mark = 0, None + for i,x in enumerate(file_stat): + sum += x[1] + if sum > self.limit: + mark = i + break + if mark == None: + return [] + else: + return [x[0] for x in file_stat[mark:]] + + def convert_size(self, size_bytes): + if size_bytes == 0: + return "0 bytes" + size_name = ("bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") + i = int(math.floor(math.log(size_bytes, 1024))) + p = math.pow(1024, i) + s = round(size_bytes / p, 2) + return "%s %s" % (int(s) if i == 0 else s, size_name[i]) + + def get_size(self, start_path = '.'): + total_size = 0 + for dirpath, dirnames, filenames in os.walk(start_path): + for f in filenames: + fp = os.path.join(dirpath, f) + total_size += os.path.getsize(fp) + return total_size + + def progress_finish(target, source, env): + global node_count, progressor + with open(node_count_fname, 'w') as f: + f.write('%d\n' % node_count) + progressor.delete(progressor.file_list()) + + try: + with open(node_count_fname) as f: + node_count_max = int(f.readline()) + except: + pass + + cache_directory = os.environ.get("SCONS_CACHE") + # Simple cache pruning, attached to SCons' progress callback. Trim the + # cache directory to a size not larger than cache_limit. + cache_limit = float(os.getenv("SCONS_CACHE_LIMIT", 1024)) * 1024 * 1024 + progressor = cache_progress(cache_directory, cache_limit) + Progress(progressor, interval = node_count_interval) + + progress_finish_command = Command('progress_finish', [], progress_finish) + AlwaysBuild(progress_finish_command) diff --git a/core/SCsub b/core/SCsub index af83b49fea..383aaf0e12 100644 --- a/core/SCsub +++ b/core/SCsub @@ -18,9 +18,8 @@ gd_cpp = '#include "project_settings.h"\n' gd_cpp += gd_inc gd_cpp += "void ProjectSettings::register_global_defaults() {\n" + gd_call + "\n}\n" -f = open("global_defaults.gen.cpp", "w") -f.write(gd_cpp) -f.close() +with open("global_defaults.gen.cpp", "w") as f: + f.write(gd_cpp) # Generate AES256 script encryption key @@ -47,9 +46,8 @@ if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ): txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0" print("Invalid AES256 encryption key, not 64 bits hex: " + e) -f = open("script_encryption_key.gen.cpp", "w") -f.write("#include \"project_settings.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n") -f.close() +with open("script_encryption_key.gen.cpp", "w") as f: + f.write("#include \"project_settings.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n") # Add required thirdparty code. Header paths are hardcoded, we don't need to append @@ -68,7 +66,6 @@ thirdparty_sources = [ "md5.cpp", "pcg.cpp", "triangulator.cpp", - "clipper.cpp", ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env.add_source_files(env.core_sources, thirdparty_sources) diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index b57b24ee7d..20adf7ff02 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -205,6 +205,22 @@ String _OS::get_clipboard() const { return OS::get_singleton()->get_clipboard(); } +int _OS::get_video_driver_count() const { + return OS::get_singleton()->get_video_driver_count(); +} + +String _OS::get_video_driver_name(int p_driver) const { + return OS::get_singleton()->get_video_driver_name(p_driver); +} + +int _OS::get_audio_driver_count() const { + return OS::get_singleton()->get_audio_driver_count(); +} + +String _OS::get_audio_driver_name(int p_driver) const { + return OS::get_singleton()->get_audio_driver_name(p_driver); +} + void _OS::set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen) { OS::VideoMode vm; @@ -1015,6 +1031,11 @@ void _OS::_bind_methods() { //ClassDB::bind_method(D_METHOD("is_video_mode_resizable","screen"),&_OS::is_video_mode_resizable,DEFVAL(0)); //ClassDB::bind_method(D_METHOD("get_fullscreen_mode_list","screen"),&_OS::get_fullscreen_mode_list,DEFVAL(0)); + ClassDB::bind_method(D_METHOD("get_video_driver_count"), &_OS::get_video_driver_count); + ClassDB::bind_method(D_METHOD("get_video_driver_name"), &_OS::get_video_driver_name); + ClassDB::bind_method(D_METHOD("get_audio_driver_count"), &_OS::get_audio_driver_count); + ClassDB::bind_method(D_METHOD("get_audio_driver_name"), &_OS::get_audio_driver_name); + ClassDB::bind_method(D_METHOD("get_screen_count"), &_OS::get_screen_count); ClassDB::bind_method(D_METHOD("get_current_screen"), &_OS::get_current_screen); ClassDB::bind_method(D_METHOD("set_current_screen", "screen"), &_OS::set_current_screen); @@ -1514,6 +1535,17 @@ bool _File::is_open() const { return f != NULL; } +String _File::get_path() const { + + ERR_FAIL_COND_V(!f, ""); + return f->get_path(); +} + +String _File::get_path_absolute() const { + + ERR_FAIL_COND_V(!f, ""); + return f->get_path_absolute(); +} void _File::seek(int64_t p_position) { @@ -1803,6 +1835,8 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("open", "path", "flags"), &_File::open); ClassDB::bind_method(D_METHOD("close"), &_File::close); + ClassDB::bind_method(D_METHOD("get_path"), &_File::get_path); + ClassDB::bind_method(D_METHOD("get_path_absolute"), &_File::get_path_absolute); ClassDB::bind_method(D_METHOD("is_open"), &_File::is_open); ClassDB::bind_method(D_METHOD("seek", "position"), &_File::seek); ClassDB::bind_method(D_METHOD("seek_end", "position"), &_File::seek_end, DEFVAL(0)); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 734b57937a..c40abd51f6 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -146,6 +146,12 @@ public: bool is_video_mode_resizable(int p_screen = 0) const; Array get_fullscreen_mode_list(int p_screen = 0) const; + virtual int get_video_driver_count() const; + virtual String get_video_driver_name(int p_driver) const; + + virtual int get_audio_driver_count() const; + virtual String get_audio_driver_name(int p_driver) const; + virtual int get_screen_count() const; virtual int get_current_screen() const; virtual void set_current_screen(int p_screen); @@ -409,6 +415,9 @@ public: void close(); ///< close a file bool is_open() const; ///< true when file is open + String get_path() const; /// returns the path for the current open file + String get_path_absolute() const; /// returns the absolute path for the current open file + void seek(int64_t p_position); ///< seek to a given position void seek_end(int64_t p_position = 0); ///< seek from the end of file int64_t get_position() const; ///< get position in the file diff --git a/core/class_db.cpp b/core/class_db.cpp index afcc8de0f2..92aa131e2d 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -33,18 +33,9 @@ #include "os/mutex.h" #include "version.h" -#ifdef NO_THREADS - -#define OBJTYPE_RLOCK -#define OBJTYPE_WLOCK - -#else - #define OBJTYPE_RLOCK RWLockRead _rw_lockr_(lock); #define OBJTYPE_WLOCK RWLockWrite _rw_lockw_(lock); -#endif - #ifdef DEBUG_METHODS_ENABLED MethodDefinition D_METHOD(const char *p_name) { @@ -347,7 +338,7 @@ uint64_t ClassDB::get_api_hash(APIType p_api) { OBJTYPE_RLOCK; #ifdef DEBUG_METHODS_ENABLED - uint64_t hash = hash_djb2_one_64(HashMapHasherDefault::hash(VERSION_FULL_NAME)); + uint64_t hash = hash_djb2_one_64(HashMapHasherDefault::hash(VERSION_FULL_CONFIG)); List<StringName> names; @@ -660,7 +651,6 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName } type->constant_map[p_name] = p_constant; -#ifdef DEBUG_METHODS_ENABLED String enum_name = p_enum; if (enum_name != String()) { @@ -679,6 +669,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName } } +#ifdef DEBUG_METHODS_ENABLED type->constant_order.push_back(p_name); #endif } @@ -734,7 +725,6 @@ int ClassDB::get_integer_constant(const StringName &p_class, const StringName &p return 0; } -#ifdef DEBUG_METHODS_ENABLED StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { OBJTYPE_RLOCK; @@ -803,7 +793,6 @@ void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_ type = type->inherits_ptr; } } -#endif void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) { @@ -895,15 +884,9 @@ void ClassDB::add_property_group(StringName p_class, const String &p_name, const void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) { -#ifndef NO_THREADS lock->read_lock(); -#endif - ClassInfo *type = classes.getptr(p_class); - -#ifndef NO_THREADS lock->read_unlock(); -#endif ERR_FAIL_COND(!type); @@ -1380,10 +1363,7 @@ RWLock *ClassDB::lock = NULL; void ClassDB::init() { -#ifndef NO_THREADS - lock = RWLock::create(); -#endif } void ClassDB::cleanup() { @@ -1406,10 +1386,7 @@ void ClassDB::cleanup() { resource_base_extensions.clear(); compat_classes.clear(); -#ifndef NO_THREADS - memdelete(lock); -#endif } // diff --git a/core/class_db.h b/core/class_db.h index d74317239b..2c77ffe65f 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -116,10 +116,10 @@ public: ClassInfo *inherits_ptr; HashMap<StringName, MethodBind *, StringNameHasher> method_map; HashMap<StringName, int, StringNameHasher> constant_map; + HashMap<StringName, List<StringName> > enum_map; HashMap<StringName, MethodInfo, StringNameHasher> signal_map; List<PropertyInfo> property_list; #ifdef DEBUG_METHODS_ENABLED - HashMap<StringName, List<StringName> > enum_map; List<StringName> constant_order; List<StringName> method_order; Set<StringName> methods_in_properties; @@ -344,11 +344,9 @@ public: static void get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance = false); static int get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success = NULL); -#ifdef DEBUG_METHODS_ENABLED static StringName get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false); static void get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance = false); static void get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance = false); -#endif static StringName get_category(const StringName &p_node); diff --git a/core/color.cpp b/core/color.cpp index 27d8e9b891..b2f5889166 100644 --- a/core/color.cpp +++ b/core/color.cpp @@ -402,6 +402,10 @@ String Color::to_html(bool p_alpha) const { Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) { + p_h = Math::fmod(p_h * 360.0f, 360.0f); + if (p_h < 0.0) + p_h += 360.0f; + const float h_ = p_h / 60.0f; const float c = p_v * p_s; const float x = c * (1.0f - Math::abs(Math::fmod(h_, 2.0f) - 1.0f)); diff --git a/core/command_queue_mt.cpp b/core/command_queue_mt.cpp index 6bb3135757..a39c920dfa 100644 --- a/core/command_queue_mt.cpp +++ b/core/command_queue_mt.cpp @@ -105,6 +105,7 @@ CommandQueueMT::CommandQueueMT(bool p_sync) { read_ptr = 0; write_ptr = 0; + dealloc_ptr = 0; mutex = Mutex::create(); for (int i = 0; i < SYNC_SEMAPHORES; i++) { diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h index cecc9e405d..3942b961d3 100644 --- a/core/command_queue_mt.h +++ b/core/command_queue_mt.h @@ -55,7 +55,7 @@ #define _COMMA_11 , #define _COMMA_12 , -// 1-based comma separed list of ITEMs +// 1-based comma separated list of ITEMs #define COMMA_SEP_LIST(ITEM, LENGTH) _COMMA_SEP_LIST_##LENGTH(ITEM) #define _COMMA_SEP_LIST_12(ITEM) \ _COMMA_SEP_LIST_11(ITEM) \ @@ -95,7 +95,7 @@ ITEM(1) #define _COMMA_SEP_LIST_0(ITEM) -// 1-based semicolon separed list of ITEMs +// 1-based semicolon separated list of ITEMs #define SEMIC_SEP_LIST(ITEM, LENGTH) _SEMIC_SEP_LIST_##LENGTH(ITEM) #define _SEMIC_SEP_LIST_12(ITEM) \ _SEMIC_SEP_LIST_11(ITEM); \ @@ -135,7 +135,7 @@ ITEM(1) #define _SEMIC_SEP_LIST_0(ITEM) -// 1-based space separed list of ITEMs +// 1-based space separated list of ITEMs #define SPACE_SEP_LIST(ITEM, LENGTH) _SPACE_SEP_LIST_##LENGTH(ITEM) #define _SPACE_SEP_LIST_12(ITEM) \ _SPACE_SEP_LIST_11(ITEM) \ diff --git a/core/compressed_translation.h b/core/compressed_translation.h index 400fa4491b..ccc47d0bf6 100644 --- a/core/compressed_translation.h +++ b/core/compressed_translation.h @@ -38,7 +38,7 @@ class PHashTranslation : public Translation { GDCLASS(PHashTranslation, Translation); //this translation uses a sort of modified perfect hash algorithm - //it requieres hashing strings twice and then does a binary search, + //it requires hashing strings twice and then does a binary search, //so it's slower, but at the same time it has an extreemly high chance //of catching untranslated strings diff --git a/core/error_macros.h b/core/error_macros.h index 1f9164a99b..b8d0c7e0c3 100644 --- a/core/error_macros.h +++ b/core/error_macros.h @@ -33,7 +33,7 @@ #include "typedefs.h" /** - * Error macros. Unlike exceptions and asserts, these macros try to mantain consistency and stability + * Error macros. Unlike exceptions and asserts, these macros try to maintain consistency and stability * inside the code. It is recommended to always return processable data, so in case of an error, the * engine can stay working well. * In most cases, bugs and/or invalid data are not fatal and should never allow a perfectly running application diff --git a/core/global_constants.cpp b/core/global_constants.cpp index a24bf03c9a..04810afe73 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -580,7 +580,7 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_COLOR_ARRAY", Variant::POOL_COLOR_ARRAY); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_MAX", Variant::VARIANT_MAX); - //comparation + //comparison BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_EQUAL", Variant::OP_EQUAL); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_NOT_EQUAL", Variant::OP_NOT_EQUAL); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("OP_LESS", Variant::OP_LESS); diff --git a/core/input_map.cpp b/core/input_map.cpp index a9ea1d9545..bd03d61196 100644 --- a/core/input_map.cpp +++ b/core/input_map.cpp @@ -282,6 +282,16 @@ void InputMap::load_default() { key->set_scancode(KEY_PAGEDOWN); action_add_event("ui_page_down", key); + add_action("ui_home"); + key.instance(); + key->set_scancode(KEY_HOME); + action_add_event("ui_home", key); + + add_action("ui_end"); + key.instance(); + key->set_scancode(KEY_END); + action_add_event("ui_end", key); + //set("display/window/handheld/orientation", "landscape"); } diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index 1a16d0f61c..efb4c7a073 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -88,7 +88,11 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o } } } - cd->files.insert(path.get_file()); + String filename = path.get_file(); + // Don't add as a file if the path points to a directoryy + if (!filename.empty()) { + cd->files.insert(filename); + } } } diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index a9eb9466b7..4d72f744e1 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -298,7 +298,7 @@ Error HTTPClient::poll() { case StreamPeerTCP::STATUS_CONNECTED: { if (ssl) { Ref<StreamPeerSSL> ssl = StreamPeerSSL::create(); - Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, ssl_verify_host ? conn_host : String()); + Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host); if (err != OK) { close(); status = STATUS_SSL_HANDSHAKE_ERROR; diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp index 7261363ad6..6d979d10eb 100644 --- a/core/io/ip_address.cpp +++ b/core/io/ip_address.cpp @@ -211,7 +211,7 @@ IP_Address::IP_Address(const String &p_string) { clear(); if (p_string == "*") { - // Wildcard (not a vaild IP) + // Wildcard (not a valid IP) wildcard = true; } else if (p_string.find(":") >= 0) { diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 9e21287780..2ebe8d6df7 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -813,7 +813,7 @@ static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) { while (r_len % 4) { r_len++; //pad if (buf) { - buf++; + *(buf++) = 0; } } } diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp index 07a01ff99f..012ba78c6d 100644 --- a/core/io/stream_peer_ssl.cpp +++ b/core/io/stream_peer_ssl.cpp @@ -29,6 +29,8 @@ /*************************************************************************/ #include "stream_peer_ssl.h" +#include "os/file_access.h" +#include "project_settings.h" StreamPeerSSL *(*StreamPeerSSL::_create)() = NULL; @@ -50,6 +52,35 @@ bool StreamPeerSSL::is_available() { return available; } +PoolByteArray StreamPeerSSL::get_project_cert_array() { + + PoolByteArray out; + String certs_path = GLOBAL_DEF("network/ssl/certificates", ""); + ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt")); + + if (certs_path != "") { + + FileAccess *f = FileAccess::open(certs_path, FileAccess::READ); + if (f) { + int flen = f->get_len(); + out.resize(flen + 1); + { + PoolByteArray::Write w = out.write(); + f->get_buffer(w.ptr(), flen); + w[flen] = 0; //end f string + } + + memdelete(f); + +#ifdef DEBUG_ENABLED + print_line("Loaded certs from '" + certs_path); +#endif + } + } + + return out; +} + void StreamPeerSSL::_bind_methods() { ClassDB::bind_method(D_METHOD("poll"), &StreamPeerSSL::poll); diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h index f903438c28..77301a7c87 100644 --- a/core/io/stream_peer_ssl.h +++ b/core/io/stream_peer_ssl.h @@ -66,6 +66,7 @@ public: static StreamPeerSSL *create(); + static PoolByteArray get_project_cert_array(); static void load_certs_from_memory(const PoolByteArray &p_memory); static bool is_available(); diff --git a/core/make_binders.py b/core/make_binders.py index 1e581f8ce3..6a7602cd5d 100644 --- a/core/make_binders.py +++ b/core/make_binders.py @@ -265,10 +265,8 @@ def run(target, source, env): else: text += t - f = open(target[0].path, "w") - f.write(text) - f.close() + with open(target[0].path, "w") as f: + f.write(text) - f = open(target[1].path, "w") - f.write(text_ext) - f.close() + with open(target[1].path, "w") as f: + f.write(text_ext) diff --git a/core/map.h b/core/map.h index 5ff269c26b..700d4b8693 100644 --- a/core/map.h +++ b/core/map.h @@ -197,7 +197,7 @@ private: if (node->right != _data._nil) { node = node->right; - while (node->left != _data._nil) { /* returns the minium of the right subtree of node */ + while (node->left != _data._nil) { /* returns the minimum of the right subtree of node */ node = node->left; } return node; @@ -219,7 +219,7 @@ private: if (node->left != _data._nil) { node = node->left; - while (node->right != _data._nil) { /* returns the minium of the left subtree of node */ + while (node->right != _data._nil) { /* returns the minimum of the left subtree of node */ node = node->right; } return node; diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp index d2e4101999..3767d298a1 100644 --- a/core/math/math_2d.cpp +++ b/core/math/math_2d.cpp @@ -98,11 +98,6 @@ real_t Vector2::cross(const Vector2 &p_other) const { return x * p_other.y - y * p_other.x; } -Vector2 Vector2::cross(real_t p_other) const { - - return Vector2(p_other * y, -p_other * x); -} - Vector2 Vector2::floor() const { return Vector2(Math::floor(x), Math::floor(y)); diff --git a/core/math/math_2d.h b/core/math/math_2d.h index 8928349a44..e7188da85b 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -104,7 +104,6 @@ struct Vector2 { real_t dot(const Vector2 &p_other) const; real_t cross(const Vector2 &p_other) const; - Vector2 cross(real_t p_other) const; Vector2 project(const Vector2 &p_vec) const; Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const; @@ -304,7 +303,7 @@ struct Rect2 { inline real_t distance_to(const Vector2 &p_point) const { - real_t dist; + real_t dist = 0.0; bool inside = true; if (p_point.x < position.x) { diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index f060a8e4ab..5c8512d8bd 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -177,18 +177,3 @@ float Math::random(float from, float to) { float ret = (float)r / (float)RANDOM_MAX; return (ret) * (to - from) + from; } - -int Math::wrapi(int value, int min, int max) { - --max; - int rng = max - min + 1; - value = ((value - min) % rng); - if (value < 0) - return max + 1 + value; - else - return min + value; -} - -float Math::wrapf(float value, float min, float max) { - float rng = max - min; - return min + (value - min) - (rng * floor((value - min) / rng)); -} diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index e15abc6b50..26e87f009b 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -209,8 +209,18 @@ public: static _ALWAYS_INLINE_ double round(double p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); } static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); } - static int wrapi(int value, int min, int max); - static float wrapf(float value, float min, float max); + static _ALWAYS_INLINE_ int wrapi(int value, int min, int max) { + int rng = max - min; + return min + ((((value - min) % rng) + rng) % rng); + } + static _ALWAYS_INLINE_ double wrapf(double value, double min, double max) { + double rng = max - min; + return min + (value - min) - (rng * Math::floor((value - min) / rng)); + } + static _ALWAYS_INLINE_ float wrapf(float value, float min, float max) { + float rng = max - min; + return min + (value - min) - (rng * Math::floor((value - min) / rng)); + } // double only, as these functions are mainly used by the editor and not performance-critical, static double ease(double p_x, double p_c); diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp index 5bae74ac7e..563ba7268f 100644 --- a/core/math/triangulate.cpp +++ b/core/math/triangulate.cpp @@ -51,7 +51,8 @@ real_t Triangulate::get_area(const Vector<Vector2> &contour) { bool Triangulate::is_inside_triangle(real_t Ax, real_t Ay, real_t Bx, real_t By, real_t Cx, real_t Cy, - real_t Px, real_t Py) + real_t Px, real_t Py, + bool include_edges) { real_t ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy; @@ -74,10 +75,14 @@ bool Triangulate::is_inside_triangle(real_t Ax, real_t Ay, cCROSSap = cx * apy - cy * apx; bCROSScp = bx * cpy - by * cpx; - return ((aCROSSbp > 0.0) && (bCROSScp > 0.0) && (cCROSSap > 0.0)); + if (include_edges) { + return ((aCROSSbp > 0.0) && (bCROSScp > 0.0) && (cCROSSap > 0.0)); + } else { + return ((aCROSSbp >= 0.0) && (bCROSScp >= 0.0) && (cCROSSap >= 0.0)); + } }; -bool Triangulate::snip(const Vector<Vector2> &p_contour, int u, int v, int w, int n, const Vector<int> &V) { +bool Triangulate::snip(const Vector<Vector2> &p_contour, int u, int v, int w, int n, const Vector<int> &V, bool relaxed) { int p; real_t Ax, Ay, Bx, By, Cx, Cy, Px, Py; const Vector2 *contour = &p_contour[0]; @@ -91,13 +96,20 @@ bool Triangulate::snip(const Vector<Vector2> &p_contour, int u, int v, int w, in Cx = contour[V[w]].x; Cy = contour[V[w]].y; - if (CMP_EPSILON > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) return false; + // It can happen that the triangulation ends up with three aligned vertices to deal with. + // In this scenario, making the check below strict may reject the possibility of + // forming a last triangle with these aligned vertices, preventing the triangulatiom + // from completing. + // To avoid that we allow zero-area triangles if all else failed. + float threshold = relaxed ? -CMP_EPSILON : CMP_EPSILON; + + if (threshold > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) return false; for (p = 0; p < n; p++) { if ((p == u) || (p == v) || (p == w)) continue; Px = contour[V[p]].x; Py = contour[V[p]].y; - if (is_inside_triangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py)) return false; + if (is_inside_triangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py, relaxed)) return false; } return true; @@ -121,6 +133,8 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul for (int v = 0; v < n; v++) V[v] = (n - 1) - v; + bool relaxed = false; + int nv = n; /* remove nv-2 Vertices, creating 1 triangle every time */ @@ -129,8 +143,20 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul for (int v = nv - 1; nv > 2;) { /* if we loop, it is probably a non-simple polygon */ if (0 >= (count--)) { - //** Triangulate: ERROR - probable bad polygon! - return false; + if (relaxed) { + //** Triangulate: ERROR - probable bad polygon! + return false; + } else { + // There may be aligned vertices that the strict + // checks prevent from triangulating. In this situation + // we are better off adding flat triangles than + // failing, so we relax the checks and try one last + // round. + // Only relaxing the constraints as a last resort avoids + // degenerate triangles when they aren't necessary. + count = 2 * nv; + relaxed = true; + } } /* three consecutive vertices in current polygon, <u,v,w> */ @@ -141,7 +167,7 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul int w = v + 1; if (nv <= w) w = 0; /* next */ - if (snip(contour, u, v, w, nv, V)) { + if (snip(contour, u, v, w, nv, V, relaxed)) { int a, b, c, s, t; /* true names of the vertices */ diff --git a/core/math/triangulate.h b/core/math/triangulate.h index e336dc5756..b1a583d0c5 100644 --- a/core/math/triangulate.h +++ b/core/math/triangulate.h @@ -51,10 +51,11 @@ public: static bool is_inside_triangle(real_t Ax, real_t Ay, real_t Bx, real_t By, real_t Cx, real_t Cy, - real_t Px, real_t Py); + real_t Px, real_t Py, + bool include_edges); private: - static bool snip(const Vector<Vector2> &p_contour, int u, int v, int w, int n, const Vector<int> &V); + static bool snip(const Vector<Vector2> &p_contour, int u, int v, int w, int n, const Vector<int> &V, bool relaxed); }; #endif diff --git a/core/message_queue.cpp b/core/message_queue.cpp index 3ceafe1a30..25ee6eafae 100644 --- a/core/message_queue.cpp +++ b/core/message_queue.cpp @@ -278,7 +278,7 @@ void MessageQueue::flush() { while (read_pos < buffer_end) { - //lock on each interation, so a call can re-add itself to the message queue + //lock on each iteration, so a call can re-add itself to the message queue Message *message = (Message *)&buffer[read_pos]; diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp index 1941b82602..330a9153ef 100644 --- a/core/os/dir_access.cpp +++ b/core/os/dir_access.cpp @@ -301,8 +301,8 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) { FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ, &err); if (err) { - - ERR_FAIL_COND_V(err, err); + ERR_PRINTS("Failed to open " + p_from); + return err; } FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE, &err); @@ -310,7 +310,8 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) { fsrc->close(); memdelete(fsrc); - ERR_FAIL_COND_V(err, err); + ERR_PRINTS("Failed to open " + p_to); + return err; } fsrc->seek_end(0); diff --git a/core/os/file_access.h b/core/os/file_access.h index 5d10c1a9aa..c4635fdfbb 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -89,6 +89,9 @@ public: virtual void close() = 0; ///< close a file virtual bool is_open() const = 0; ///< true when file is open + virtual String get_path() const { return ""; } /// returns the path for the current open file + virtual String get_path_absolute() const { return ""; } /// returns the absolute path for the current open file + virtual void seek(size_t p_position) = 0; ///< seek to a given position virtual void seek_end(int64_t p_position = 0) = 0; ///< seek from the end of file virtual size_t get_position() const = 0; ///< get position in the file diff --git a/core/os/input.cpp b/core/os/input.cpp index 3089ab2ce3..1d7cd7c791 100644 --- a/core/os/input.cpp +++ b/core/os/input.cpp @@ -111,7 +111,7 @@ void Input::_bind_methods() { BIND_ENUM_CONSTANT(CURSOR_HSPLIT); BIND_ENUM_CONSTANT(CURSOR_HELP); - ADD_SIGNAL(MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::BOOL, "connected"))); + ADD_SIGNAL(MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "device"), PropertyInfo(Variant::BOOL, "connected"))); } void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index 12060f31df..b9607632f7 100644 --- a/core/os/input_event.cpp +++ b/core/os/input_event.cpp @@ -962,6 +962,11 @@ Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform, return ev; } +String InputEventMagnifyGesture::as_text() const { + + return "InputEventMagnifyGesture : factor=" + rtos(get_factor()) + ", position=(" + String(get_position()) + ")"; +} + void InputEventMagnifyGesture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_factor", "factor"), &InputEventMagnifyGesture::set_factor); @@ -999,6 +1004,11 @@ Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, con return ev; } +String InputEventPanGesture::as_text() const { + + return "InputEventPanGesture : delta=(" + String(get_delta()) + "), position=(" + String(get_position()) + ")"; +} + void InputEventPanGesture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_delta", "delta"), &InputEventPanGesture::set_delta); diff --git a/core/os/input_event.h b/core/os/input_event.h index ad754d0d1f..0a33ab18a7 100644 --- a/core/os/input_event.h +++ b/core/os/input_event.h @@ -494,6 +494,7 @@ public: real_t get_factor() const; virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; + virtual String as_text() const; InputEventMagnifyGesture(); }; @@ -511,6 +512,7 @@ public: Vector2 get_delta() const; virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; + virtual String as_text() const; InputEventPanGesture(); }; diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp index fa53cc85c8..9dfc91e308 100644 --- a/core/os/keyboard.cpp +++ b/core/os/keyboard.cpp @@ -461,99 +461,6 @@ const char *find_keycode_name(int p_keycode) { return ""; } -struct _KeyCodeReplace { - int from; - int to; -}; - -static const _KeyCodeReplace _keycode_replace_qwertz[] = { - { KEY_Y, KEY_Z }, - { KEY_Z, KEY_Y }, - { 0, 0 } -}; - -static const _KeyCodeReplace _keycode_replace_azerty[] = { - { KEY_W, KEY_Z }, - { KEY_Z, KEY_W }, - { KEY_A, KEY_Q }, - { KEY_Q, KEY_A }, - { KEY_SEMICOLON, KEY_M }, - { KEY_M, KEY_SEMICOLON }, - { 0, 0 } -}; - -static const _KeyCodeReplace _keycode_replace_qzerty[] = { - { KEY_W, KEY_Z }, - { KEY_Z, KEY_W }, - { KEY_SEMICOLON, KEY_M }, - { KEY_M, KEY_SEMICOLON }, - { 0, 0 } -}; - -static const _KeyCodeReplace _keycode_replace_dvorak[] = { - { KEY_UNDERSCORE, KEY_BRACELEFT }, - { KEY_EQUAL, KEY_BRACERIGHT }, - { KEY_Q, KEY_APOSTROPHE }, - { KEY_W, KEY_COMMA }, - { KEY_E, KEY_PERIOD }, - { KEY_R, KEY_P }, - { KEY_T, KEY_Y }, - { KEY_Y, KEY_F }, - { KEY_U, KEY_G }, - { KEY_I, KEY_C }, - { KEY_O, KEY_R }, - { KEY_P, KEY_L }, - { KEY_BRACELEFT, KEY_SLASH }, - { KEY_BRACERIGHT, KEY_EQUAL }, - { KEY_A, KEY_A }, - { KEY_S, KEY_O }, - { KEY_D, KEY_E }, - { KEY_F, KEY_U }, - { KEY_G, KEY_I }, - { KEY_H, KEY_D }, - { KEY_J, KEY_H }, - { KEY_K, KEY_T }, - { KEY_L, KEY_N }, - { KEY_SEMICOLON, KEY_S }, - { KEY_APOSTROPHE, KEY_UNDERSCORE }, - { KEY_Z, KEY_SEMICOLON }, - { KEY_X, KEY_Q }, - { KEY_C, KEY_J }, - { KEY_V, KEY_K }, - { KEY_B, KEY_X }, - { KEY_N, KEY_B }, - { KEY_M, KEY_M }, - { KEY_COMMA, KEY_W }, - { KEY_PERIOD, KEY_V }, - { KEY_SLASH, KEY_Z }, - { 0, 0 } -}; - -static const _KeyCodeReplace _keycode_replace_neo[] = { - { 0, 0 } -}; - -static const _KeyCodeReplace _keycode_replace_colemak[] = { - { KEY_E, KEY_F }, - { KEY_R, KEY_P }, - { KEY_T, KEY_G }, - { KEY_Y, KEY_J }, - { KEY_U, KEY_L }, - { KEY_I, KEY_U }, - { KEY_O, KEY_Y }, - { KEY_P, KEY_SEMICOLON }, - { KEY_S, KEY_R }, - { KEY_D, KEY_S }, - { KEY_F, KEY_T }, - { KEY_G, KEY_D }, - { KEY_J, KEY_N }, - { KEY_K, KEY_E }, - { KEY_L, KEY_I }, - { KEY_SEMICOLON, KEY_O }, - { KEY_N, KEY_K }, - { 0, 0 } -}; - int keycode_get_count() { const _KeyCodeText *kct = &_keycodes[0]; @@ -574,31 +481,3 @@ int keycode_get_value_by_index(int p_index) { const char *keycode_get_name_by_index(int p_index) { return _keycodes[p_index].text; } - -int latin_keyboard_keycode_convert(int p_keycode) { - - const _KeyCodeReplace *kcr = NULL; - switch (OS::get_singleton()->get_latin_keyboard_variant()) { - - case OS::LATIN_KEYBOARD_QWERTY: return p_keycode; break; - case OS::LATIN_KEYBOARD_QWERTZ: kcr = _keycode_replace_qwertz; break; - case OS::LATIN_KEYBOARD_AZERTY: kcr = _keycode_replace_azerty; break; - case OS::LATIN_KEYBOARD_QZERTY: kcr = _keycode_replace_qzerty; break; - case OS::LATIN_KEYBOARD_DVORAK: kcr = _keycode_replace_dvorak; break; - case OS::LATIN_KEYBOARD_NEO: kcr = _keycode_replace_neo; break; - case OS::LATIN_KEYBOARD_COLEMAK: kcr = _keycode_replace_colemak; break; - default: return p_keycode; - } - - if (!kcr) { - return p_keycode; - } - - while (kcr->from) { - if (kcr->from == p_keycode) - return kcr->to; - kcr++; - } - - return p_keycode; -} diff --git a/core/os/keyboard.h b/core/os/keyboard.h index 4c253fa4ce..a0e6f8b2ef 100644 --- a/core/os/keyboard.h +++ b/core/os/keyboard.h @@ -331,6 +331,5 @@ const char *find_keycode_name(int p_keycode); int keycode_get_count(); int keycode_get_value_by_index(int p_index); const char *keycode_get_name_by_index(int p_index); -int latin_keyboard_keycode_convert(int p_keycode); #endif diff --git a/core/os/os.cpp b/core/os/os.cpp index 422acf95dc..618a4bbac3 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -34,6 +34,7 @@ #include "input.h" #include "os/file_access.h" #include "project_settings.h" +#include "servers/audio_server.h" #include "version_generated.gen.h" #include <stdarg.h> @@ -627,6 +628,34 @@ void OS::center_window() { set_window_position(Vector2(x, y)); } +int OS::get_video_driver_count() const { + + return 2; +} + +const char *OS::get_video_driver_name(int p_driver) const { + + switch (p_driver) { + case VIDEO_DRIVER_GLES2: + return "GLES2"; + case VIDEO_DRIVER_GLES3: + default: + return "GLES3"; + } +} + +int OS::get_audio_driver_count() const { + + return AudioDriverManager::get_driver_count(); +} + +const char *OS::get_audio_driver_name(int p_driver) const { + + AudioDriver *driver = AudioDriverManager::get_driver(p_driver); + ERR_FAIL_COND_V(!driver, ""); + return AudioDriverManager::get_driver(p_driver)->get_name(); +} + OS::OS() { void *volatile stack_bottom; diff --git a/core/os/os.h b/core/os/os.h index 38e55fa3b7..5a2c998782 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -44,6 +44,12 @@ @author Juan Linietsky <reduzio@gmail.com> */ +enum VideoDriver { + VIDEO_DRIVER_GLES3, + VIDEO_DRIVER_GLES2, + VIDEO_DRIVER_MAX, +}; + class OS { static OS *singleton; @@ -115,12 +121,6 @@ protected: RenderThreadMode _render_thread_mode; // functions used by main to initialize/deintialize the OS - virtual int get_video_driver_count() const = 0; - virtual const char *get_video_driver_name(int p_driver) const = 0; - - virtual int get_audio_driver_count() const = 0; - virtual const char *get_audio_driver_name(int p_driver) const = 0; - void add_logger(Logger *p_logger); virtual void initialize_core() = 0; @@ -175,6 +175,12 @@ public: virtual VideoMode get_video_mode(int p_screen = 0) const = 0; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const = 0; + virtual int get_video_driver_count() const; + virtual const char *get_video_driver_name(int p_driver) const; + + virtual int get_audio_driver_count() const; + virtual const char *get_audio_driver_name(int p_driver) const; + virtual int get_screen_count() const { return 1; } virtual int get_current_screen() const { return 0; } virtual void set_current_screen(int p_screen) {} diff --git a/core/os/thread_dummy.cpp b/core/os/thread_dummy.cpp index fa0bb3dafd..b6371235c4 100644 --- a/core/os/thread_dummy.cpp +++ b/core/os/thread_dummy.cpp @@ -55,3 +55,11 @@ Semaphore *SemaphoreDummy::create() { void SemaphoreDummy::make_default() { Semaphore::create_func = &SemaphoreDummy::create; }; + +RWLock *RWLockDummy::create() { + return memnew(RWLockDummy); +}; + +void RWLockDummy::make_default() { + RWLock::create_func = &RWLockDummy::create; +}; diff --git a/core/os/thread_dummy.h b/core/os/thread_dummy.h index b67b52a726..74957b95fe 100644 --- a/core/os/thread_dummy.h +++ b/core/os/thread_dummy.h @@ -32,6 +32,7 @@ #define THREAD_DUMMY_H #include "mutex.h" +#include "rw_lock.h" #include "semaphore.h" #include "thread.h" @@ -69,4 +70,20 @@ public: static void make_default(); }; +class RWLockDummy : public RWLock { + + static RWLock *create(); + +public: + virtual void read_lock() {} + virtual void read_unlock() {} + virtual Error read_try_lock() { return OK; } + + virtual void write_lock() {} + virtual void write_unlock() {} + virtual Error write_try_lock() { return OK; } + + static void make_default(); +}; + #endif diff --git a/core/pool_allocator.cpp b/core/pool_allocator.cpp index d81e1912bf..017586b92a 100644 --- a/core/pool_allocator.cpp +++ b/core/pool_allocator.cpp @@ -90,7 +90,7 @@ bool PoolAllocator::find_hole(EntryArrayPos *p_pos, int p_for_size) { int hole_size = entry.pos - prev_entry_end_pos; - /* detemine if what we want fits in that hole */ + /* determine if what we want fits in that hole */ if (hole_size >= p_for_size) { *p_pos = i; return true; @@ -100,7 +100,7 @@ bool PoolAllocator::find_hole(EntryArrayPos *p_pos, int p_for_size) { prev_entry_end_pos = entry_end(entry); } - /* No holes between entrys, check at the end..*/ + /* No holes between entries, check at the end..*/ if ((pool_size - prev_entry_end_pos) >= p_for_size) { *p_pos = entry_count; diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 427fa77e62..20d91e7940 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -692,7 +692,10 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin String vstr; VariantWriter::write_to_string(value, vstr); - file->store_string(F->get() + "=" + vstr + "\n"); + if (F->get().find(" ") != -1) + file->store_string(F->get().quote() + "=" + vstr + "\n"); + else + file->store_string(F->get() + "=" + vstr + "\n"); } } @@ -1027,6 +1030,20 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("input/ui_page_down", va); input_presets.push_back("input/ui_page_down"); + va = Array(); + key.instance(); + key->set_scancode(KEY_HOME); + va.push_back(key); + GLOBAL_DEF("input/ui_home", va); + input_presets.push_back("input/ui_home"); + + va = Array(); + key.instance(); + key->set_scancode(KEY_END); + va.push_back(key); + GLOBAL_DEF("input/ui_end", va); + input_presets.push_back("input/ui_end"); + //GLOBAL_DEF("display/window/handheld/orientation", "landscape"); custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor"); diff --git a/core/reference.h b/core/reference.h index a0bdb62258..0d6b1ced6e 100644 --- a/core/reference.h +++ b/core/reference.h @@ -63,7 +63,7 @@ public: template <class T> class Ref { - T *reference = NULL; + T *reference; void ref(const Ref &p_from) { @@ -213,10 +213,9 @@ public: Ref(T *p_reference) { + reference = NULL; if (p_reference) ref_pointer(p_reference); - else - reference = NULL; } Ref(const Variant &p_variant) { diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index 41071ace5d..632285f48d 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -1016,11 +1016,11 @@ void ScriptDebuggerRemote::add_profiling_frame_data(const StringName &p_name, co } void ScriptDebuggerRemote::profiling_start() { - //ignores this, uses it via connnection + //ignores this, uses it via connection } void ScriptDebuggerRemote::profiling_end() { - //ignores this, uses it via connnection + //ignores this, uses it via connection } void ScriptDebuggerRemote::profiling_set_frame_times(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time) { diff --git a/core/script_language.h b/core/script_language.h index d1da0a3b72..0c1f99cea6 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -203,6 +203,7 @@ public: virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {} virtual bool is_using_templates() { return false; } virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const = 0; + virtual String validate_path(const String &p_path) const { return ""; } virtual Script *create_script() const = 0; virtual bool has_named_classes() const = 0; virtual bool supports_builtin_mode() const = 0; @@ -220,7 +221,9 @@ public: RESULT_CLASS, RESULT_CLASS_CONSTANT, RESULT_CLASS_PROPERTY, - RESULT_CLASS_METHOD + RESULT_CLASS_METHOD, + RESULT_CLASS_ENUM, + RESULT_CLASS_TBD_GLOBALSCOPE }; Type type; Ref<Script> script; diff --git a/core/set.h b/core/set.h index 4f17c953b1..d79dd81644 100644 --- a/core/set.h +++ b/core/set.h @@ -185,7 +185,7 @@ private: if (node->right != _data._nil) { node = node->right; - while (node->left != _data._nil) { /* returns the minium of the right subtree of node */ + while (node->left != _data._nil) { /* returns the minimum of the right subtree of node */ node = node->left; } return node; @@ -207,7 +207,7 @@ private: if (node->left != _data._nil) { node = node->left; - while (node->right != _data._nil) { /* returns the minium of the left subtree of node */ + while (node->right != _data._nil) { /* returns the minimum of the left subtree of node */ node = node->right; } return node; diff --git a/core/string_buffer.h b/core/string_buffer.h index b148e45544..7e9b151bea 100644 --- a/core/string_buffer.h +++ b/core/string_buffer.h @@ -39,7 +39,7 @@ class StringBuffer { CharType short_buffer[SHORT_BUFFER_SIZE]; String buffer; - int string_length = 0; + int string_length; _FORCE_INLINE_ CharType *current_buffer_ptr() { return static_cast<Vector<CharType> &>(buffer).empty() ? short_buffer : buffer.ptrw(); @@ -79,6 +79,10 @@ public: _FORCE_INLINE_ operator String() { return as_string(); } + + StringBuffer() { + string_length = 0; + } }; template <int SHORT_BUFFER_SIZE> diff --git a/core/string_builder.h b/core/string_builder.h index 9e2599ac32..596b3bf730 100644 --- a/core/string_builder.h +++ b/core/string_builder.h @@ -37,7 +37,7 @@ class StringBuilder { - uint32_t string_length = 0; + uint32_t string_length; Vector<String> strings; Vector<const char *> c_strings; @@ -75,6 +75,10 @@ public: _FORCE_INLINE_ operator String() const { return as_string(); } + + StringBuilder() { + string_length = 0; + } }; #endif // STRING_BUILDER_H diff --git a/core/ustring.cpp b/core/ustring.cpp index d445e4ed47..a7a7810837 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -1135,6 +1135,36 @@ String String::num_int64(int64_t p_num, int base, bool capitalize_hex) { return s; } +String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) { + + uint64_t n = p_num; + + int chars = 0; + do { + n /= base; + chars++; + } while (n); + + String s; + s.resize(chars + 1); + CharType *c = s.ptrw(); + c[chars] = 0; + n = p_num; + do { + int mod = ABS(n % base); + if (mod >= 10) { + char a = (capitalize_hex ? 'A' : 'a'); + c[--chars] = a + (mod - 10); + } else { + c[--chars] = '0' + mod; + } + + n /= base; + } while (n); + + return s; +} + String String::num_real(double p_num) { String s; diff --git a/core/ustring.h b/core/ustring.h index 90496b71b6..bb676ce623 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -146,6 +146,7 @@ public: static String num_scientific(double p_num); static String num_real(double p_num); static String num_int64(int64_t p_num, int base = 10, bool capitalize_hex = false); + static String num_uint64(uint64_t p_num, int base = 10, bool capitalize_hex = false); static String chr(CharType p_char); static String md5(const uint8_t *p_md5); static String hex_encode_buffer(const uint8_t *p_buffer, int p_len); diff --git a/core/variant.h b/core/variant.h index 51ee8ea9d1..0a4afada5b 100644 --- a/core/variant.h +++ b/core/variant.h @@ -293,7 +293,7 @@ public: // If this changes the table in variant_op must be updated enum Operator { - //comparation + //comparison OP_EQUAL, OP_NOT_EQUAL, OP_LESS, diff --git a/core/variant_call.cpp b/core/variant_call.cpp index d1d45f0e7c..cda7dccf0c 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -347,7 +347,7 @@ struct _VariantCall { VCALL_LOCALMEM1R(Vector2, bounce); VCALL_LOCALMEM1R(Vector2, reflect); VCALL_LOCALMEM0R(Vector2, angle); - //VCALL_LOCALMEM1R(Vector2,cross); + VCALL_LOCALMEM1R(Vector2, cross); VCALL_LOCALMEM0R(Vector2, abs); VCALL_LOCALMEM1R(Vector2, clamped); @@ -1517,7 +1517,7 @@ void register_variant_methods() { ADDFUNC1R(VECTOR2, VECTOR2, Vector2, slide, VECTOR2, "n", varray()); ADDFUNC1R(VECTOR2, VECTOR2, Vector2, bounce, VECTOR2, "n", varray()); ADDFUNC1R(VECTOR2, VECTOR2, Vector2, reflect, VECTOR2, "n", varray()); - //ADDFUNC1R(VECTOR2,REAL,Vector2,cross,VECTOR2,"with",varray()); + ADDFUNC1R(VECTOR2, REAL, Vector2, cross, VECTOR2, "with", varray()); ADDFUNC0R(VECTOR2, VECTOR2, Vector2, abs, varray()); ADDFUNC1R(VECTOR2, VECTOR2, Vector2, clamped, REAL, "length", varray()); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index e46fac77ee..842f5f0af6 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -147,7 +147,7 @@ Variant::operator bool() const { return booleanize(); } -// We consider all unitialized or empty types to be false based on the type's +// We consider all uninitialized or empty types to be false based on the type's // zeroiness. bool Variant::booleanize() const { return !is_zero(); @@ -177,7 +177,7 @@ bool Variant::booleanize() const { CASE_TYPE(m_prefix, m_op_name, m_name) { \ if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \ if (p_b.type == REAL) _RETURN(p_a._data.m_type m_op p_b._data._real); \ - if (p_b.type == NIL) _RETURN(!p_b.type m_op NIL); \ + if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \ \ _RETURN_FAIL \ }; @@ -252,7 +252,7 @@ bool Variant::booleanize() const { CASE_TYPE(m_prefix, m_op_name, m_name) { \ if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \ if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \ - if (p_b.type == NIL) _RETURN(!p_b.type m_op NIL); \ + if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \ \ _RETURN_FAIL \ }; @@ -278,7 +278,7 @@ bool Variant::booleanize() const { if (p_b.type == m_name) \ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \ if (p_b.type == NIL) \ - _RETURN(!p_b.type m_op NIL); \ + _RETURN(!(p_b.type m_op NIL)); \ \ _RETURN_FAIL \ }; @@ -323,7 +323,7 @@ bool Variant::booleanize() const { if (p_b.type == m_name) \ _RETURN(*p_a._data.m_sub m_op *p_b._data.m_sub); \ if (p_b.type == NIL) \ - _RETURN(!p_b.type m_op NIL); \ + _RETURN(!(p_b.type m_op NIL)); \ \ _RETURN_FAIL \ } @@ -1501,7 +1501,7 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool v->set_hsv(v->get_h(), p_value._data._real, v->get_v()); valid = true; } else if (p_index == CoreStringNames::singleton->v) { - v->set_hsv(v->get_h(), v->get_v(), p_value._data._real); + v->set_hsv(v->get_h(), v->get_s(), p_value._data._real); valid = true; } } diff --git a/core/version.h b/core/version.h index 7a55d69ad7..d39172865a 100644 --- a/core/version.h +++ b/core/version.h @@ -30,9 +30,32 @@ #include "version_generated.gen.h" +// Godot versions are of the form <major>.<minor> for the initial release, +// and then <major>.<minor>.<patch> for subsequent bugfix releases where <patch> != 0 +// That's arbitrary, but we find it pretty and it's the current policy. + +// Defines the main "branch" version. Patch versions in this branch should be +// forward-compatible. +// Example: "3.1" +#define VERSION_BRANCH "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) #ifdef VERSION_PATCH -#define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_PATCH) "." VERSION_STATUS "." VERSION_BUILD VERSION_MODULE_CONFIG +// Example: "3.1.4" +#define VERSION_NUMBER "" VERSION_BRANCH "." _MKSTR(VERSION_PATCH) #else -#define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." VERSION_STATUS "." VERSION_BUILD VERSION_MODULE_CONFIG +// Example: "3.1" +#define VERSION_NUMBER "" VERSION_BRANCH #endif // VERSION_PATCH -#define VERSION_FULL_NAME "" VERSION_NAME " v" VERSION_MKSTRING + +// Describes the full configuration of that Godot version, including the version number, +// the status (beta, stable, etc.) and potential module-specific features (e.g. mono). +// Example: "3.1.4.stable.mono" +#define VERSION_FULL_CONFIG "" VERSION_NUMBER "." VERSION_STATUS VERSION_MODULE_CONFIG + +// Similar to VERSION_FULL_CONFIG, but also includes the (potentially custom) VERSION_BUILD +// description (e.g. official, custom_build, etc.). +// Example: "3.1.4.stable.mono.official" +#define VERSION_FULL_BUILD "" VERSION_FULL_CONFIG "." VERSION_BUILD + +// Same as above, but prepended with Godot's name and a cosmetic "v" for "version". +// Example: "Godot v3.1.4.stable.official.mono" +#define VERSION_FULL_NAME "" VERSION_NAME " v" VERSION_FULL_BUILD diff --git a/doc/classes/@GDScript.xml b/doc/classes/@GDScript.xml index 2444dc4cba..07e428faad 100644 --- a/doc/classes/@GDScript.xml +++ b/doc/classes/@GDScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="@GDScript" category="Core" version="3.1-dev"> +<class name="@GDScript" category="Core" version="3.1"> <brief_description> Built-in GDScript functions. </brief_description> diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index a434c68a4f..840d884a8c 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="@GlobalScope" category="Core" version="3.1-dev"> +<class name="@GlobalScope" category="Core" version="3.1"> <brief_description> Global scope constants and variables. </brief_description> diff --git a/doc/classes/@NativeScript.xml b/doc/classes/@NativeScript.xml index cc4e97314e..2bf1dc7a7c 100644 --- a/doc/classes/@NativeScript.xml +++ b/doc/classes/@NativeScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="@NativeScript" category="Core" version="3.1-dev"> +<class name="@NativeScript" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/@VisualScript.xml b/doc/classes/@VisualScript.xml index f3a951f722..d4a924a259 100644 --- a/doc/classes/@VisualScript.xml +++ b/doc/classes/@VisualScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="@VisualScript" category="Core" version="3.1-dev"> +<class name="@VisualScript" category="Core" version="3.1"> <brief_description> Built-in visual script functions. </brief_description> diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml index c0eb8cb417..730c395f10 100644 --- a/doc/classes/AABB.xml +++ b/doc/classes/AABB.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AABB" category="Built-In Types" version="3.1-dev"> +<class name="AABB" category="Built-In Types" version="3.1"> <brief_description> Axis-Aligned Bounding Box. </brief_description> diff --git a/doc/classes/ARVRAnchor.xml b/doc/classes/ARVRAnchor.xml index 735b1a8e8f..fa93d9668c 100644 --- a/doc/classes/ARVRAnchor.xml +++ b/doc/classes/ARVRAnchor.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRAnchor" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="ARVRAnchor" inherits="Spatial" category="Core" version="3.1"> <brief_description> - Anchor point in AR Space + Anchor point in AR Space. </brief_description> <description> The ARVR Anchor point is a spatial node that maps a real world location identified by the AR platform to a position within the game world. For example, as long as plane detection in ARKit is on, ARKit will identify and update the position of planes (tables, floors, etc) and create anchors for them. diff --git a/doc/classes/ARVRCamera.xml b/doc/classes/ARVRCamera.xml index e8cf433e2b..e74b435e11 100644 --- a/doc/classes/ARVRCamera.xml +++ b/doc/classes/ARVRCamera.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRCamera" inherits="Camera" category="Core" version="3.1-dev"> +<class name="ARVRCamera" inherits="Camera" category="Core" version="3.1"> <brief_description> A camera node with a few overrules for AR/VR applied such as location tracking. </brief_description> diff --git a/doc/classes/ARVRController.xml b/doc/classes/ARVRController.xml index e9d8f9d568..9c306c3ea4 100644 --- a/doc/classes/ARVRController.xml +++ b/doc/classes/ARVRController.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRController" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="ARVRController" inherits="Spatial" category="Core" version="3.1"> <brief_description> A spatial node representing a spatially tracked controller. </brief_description> diff --git a/doc/classes/ARVRInterface.xml b/doc/classes/ARVRInterface.xml index ed59b4329b..413370ed0b 100644 --- a/doc/classes/ARVRInterface.xml +++ b/doc/classes/ARVRInterface.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRInterface" inherits="Reference" category="Core" version="3.1-dev"> +<class name="ARVRInterface" inherits="Reference" category="Core" version="3.1"> <brief_description> Base class for ARVR interface implementation. </brief_description> diff --git a/doc/classes/ARVROrigin.xml b/doc/classes/ARVROrigin.xml index 1b998815aa..80626338f2 100644 --- a/doc/classes/ARVROrigin.xml +++ b/doc/classes/ARVROrigin.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVROrigin" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="ARVROrigin" inherits="Spatial" category="Core" version="3.1"> <brief_description> Our origin point in AR/VR. </brief_description> diff --git a/doc/classes/ARVRPositionalTracker.xml b/doc/classes/ARVRPositionalTracker.xml index 2d1e85e4c4..e703de36f4 100644 --- a/doc/classes/ARVRPositionalTracker.xml +++ b/doc/classes/ARVRPositionalTracker.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRPositionalTracker" inherits="Object" category="Core" version="3.1-dev"> +<class name="ARVRPositionalTracker" inherits="Object" category="Core" version="3.1"> <brief_description> A tracked object </brief_description> diff --git a/doc/classes/ARVRServer.xml b/doc/classes/ARVRServer.xml index 8e5dc146ad..965fad1961 100644 --- a/doc/classes/ARVRServer.xml +++ b/doc/classes/ARVRServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRServer" inherits="Object" category="Core" version="3.1-dev"> +<class name="ARVRServer" inherits="Object" category="Core" version="3.1"> <brief_description> This is our AR/VR Server. </brief_description> diff --git a/doc/classes/AStar.xml b/doc/classes/AStar.xml index 1a192f861b..482566ee9f 100644 --- a/doc/classes/AStar.xml +++ b/doc/classes/AStar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AStar" inherits="Reference" category="Core" version="3.1-dev"> +<class name="AStar" inherits="Reference" category="Core" version="3.1"> <brief_description> AStar class representation that uses vectors as edges. </brief_description> diff --git a/doc/classes/AcceptDialog.xml b/doc/classes/AcceptDialog.xml index 614e2e9430..99a3f59487 100644 --- a/doc/classes/AcceptDialog.xml +++ b/doc/classes/AcceptDialog.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AcceptDialog" inherits="WindowDialog" category="Core" version="3.1-dev"> +<class name="AcceptDialog" inherits="WindowDialog" category="Core" version="3.1"> <brief_description> Base dialog for user notification. </brief_description> diff --git a/doc/classes/AnimatedSprite.xml b/doc/classes/AnimatedSprite.xml index a4892a4c71..a6521c0cd1 100644 --- a/doc/classes/AnimatedSprite.xml +++ b/doc/classes/AnimatedSprite.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AnimatedSprite" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="AnimatedSprite" inherits="Node2D" category="Core" version="3.1"> <brief_description> Sprite node that can use multiple textures for animation. </brief_description> diff --git a/doc/classes/AnimatedSprite3D.xml b/doc/classes/AnimatedSprite3D.xml index 358524d761..733d565676 100644 --- a/doc/classes/AnimatedSprite3D.xml +++ b/doc/classes/AnimatedSprite3D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AnimatedSprite3D" inherits="SpriteBase3D" category="Core" version="3.1-dev"> +<class name="AnimatedSprite3D" inherits="SpriteBase3D" category="Core" version="3.1"> <brief_description> 2D sprite node in 3D world, that can use multiple 2D textures for animation. </brief_description> diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml index 96e78bae9d..ea503f8aa9 100644 --- a/doc/classes/Animation.xml +++ b/doc/classes/Animation.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Animation" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Animation" inherits="Resource" category="Core" version="3.1"> <brief_description> Contains data used to animate everything in the engine. </brief_description> diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml index d791cd88dd..178c714a20 100644 --- a/doc/classes/AnimationPlayer.xml +++ b/doc/classes/AnimationPlayer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AnimationPlayer" inherits="Node" category="Core" version="3.1-dev"> +<class name="AnimationPlayer" inherits="Node" category="Core" version="3.1"> <brief_description> Container and player of [Animation] resources. </brief_description> diff --git a/doc/classes/AnimationTreePlayer.xml b/doc/classes/AnimationTreePlayer.xml index ca743bfb29..49b4c6b43e 100644 --- a/doc/classes/AnimationTreePlayer.xml +++ b/doc/classes/AnimationTreePlayer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AnimationTreePlayer" inherits="Node" category="Core" version="3.1-dev"> +<class name="AnimationTreePlayer" inherits="Node" category="Core" version="3.1"> <brief_description> Animation Player that uses a node graph for blending Animations. </brief_description> diff --git a/doc/classes/Area.xml b/doc/classes/Area.xml index 3c8a6a9269..5c56b5e21b 100644 --- a/doc/classes/Area.xml +++ b/doc/classes/Area.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Area" inherits="CollisionObject" category="Core" version="3.1-dev"> +<class name="Area" inherits="CollisionObject" category="Core" version="3.1"> <brief_description> General purpose area node for detection and 3D physics influence. </brief_description> @@ -192,7 +192,7 @@ <argument index="0" name="body" type="Object"> </argument> <description> - Emitted when a [PhysicsBody2D] object exits. + Emitted when a [PhysicsBody] object exits. </description> </signal> <signal name="body_shape_entered"> @@ -205,7 +205,7 @@ <argument index="3" name="area_shape" type="int"> </argument> <description> - Emitted when a [PhysicsBody2D] object enters, reporting which shapes overlapped. + Emitted when a [PhysicsBody] object enters, reporting which shapes overlapped. </description> </signal> <signal name="body_shape_exited"> @@ -218,7 +218,7 @@ <argument index="3" name="area_shape" type="int"> </argument> <description> - Emitted when a [PhysicsBody2D] object exits, reporting which shapes were overlapping. + Emitted when a [PhysicsBody] object exits, reporting which shapes were overlapping. </description> </signal> </signals> diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml index 3cfabee27f..c50ccefc4c 100644 --- a/doc/classes/Area2D.xml +++ b/doc/classes/Area2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Area2D" inherits="CollisionObject2D" category="Core" version="3.1-dev"> +<class name="Area2D" inherits="CollisionObject2D" category="Core" version="3.1"> <brief_description> 2D area for detection and 2D physics influence. </brief_description> diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 1e129d70d0..2e2176743f 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Array" category="Built-In Types" version="3.1-dev"> +<class name="Array" category="Built-In Types" version="3.1"> <brief_description> Generic array datatype. </brief_description> @@ -265,6 +265,11 @@ Searches the array in reverse order. Optionally, a start search index can be passed. If negative, the start index is considered relative to the end of the array. </description> </method> + <method name="shuffle"> + <description> + Shuffle the array such that the items will have a random order. + </description> + </method> <method name="size"> <return type="int"> </return> @@ -296,11 +301,6 @@ [/codeblock] </description> </method> - <method name="shuffle"> - <description> - Shuffle the array such that the items will have a random order. - </description> - </method> </methods> <constants> </constants> diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml index 9ea76e2702..c25044b120 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ArrayMesh" inherits="Mesh" category="Core" version="3.1-dev"> +<class name="ArrayMesh" inherits="Mesh" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/AtlasTexture.xml b/doc/classes/AtlasTexture.xml index 77ddbb3343..409c40e809 100644 --- a/doc/classes/AtlasTexture.xml +++ b/doc/classes/AtlasTexture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AtlasTexture" inherits="Texture" category="Core" version="3.1-dev"> +<class name="AtlasTexture" inherits="Texture" category="Core" version="3.1"> <brief_description> Packs multiple small textures in a single, bigger one. Helps to optimize video memory costs and render calls. </brief_description> diff --git a/doc/classes/AudioBusLayout.xml b/doc/classes/AudioBusLayout.xml index c4e111a792..c43da3e233 100644 --- a/doc/classes/AudioBusLayout.xml +++ b/doc/classes/AudioBusLayout.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioBusLayout" inherits="Resource" category="Core" version="3.1-dev"> +<class name="AudioBusLayout" inherits="Resource" category="Core" version="3.1"> <brief_description> Stores information about the audiobusses. </brief_description> diff --git a/doc/classes/AudioEffect.xml b/doc/classes/AudioEffect.xml index 4d33b458a0..acbc96e70e 100644 --- a/doc/classes/AudioEffect.xml +++ b/doc/classes/AudioEffect.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffect" inherits="Resource" category="Core" version="3.1-dev"> +<class name="AudioEffect" inherits="Resource" category="Core" version="3.1"> <brief_description> Audio Effect For Audio. </brief_description> diff --git a/doc/classes/AudioEffectAmplify.xml b/doc/classes/AudioEffectAmplify.xml index 2c0cbff8b4..3582ddc4f7 100644 --- a/doc/classes/AudioEffectAmplify.xml +++ b/doc/classes/AudioEffectAmplify.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectAmplify" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectAmplify" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Adds a Amplify audio effect to an Audio bus. Increases or decreases the volume of the selected audio bus. diff --git a/doc/classes/AudioEffectBandLimitFilter.xml b/doc/classes/AudioEffectBandLimitFilter.xml index c9e9520dfe..9eba806ad5 100644 --- a/doc/classes/AudioEffectBandLimitFilter.xml +++ b/doc/classes/AudioEffectBandLimitFilter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectBandLimitFilter" inherits="AudioEffectFilter" category="Core" version="3.1-dev"> +<class name="AudioEffectBandLimitFilter" inherits="AudioEffectFilter" category="Core" version="3.1"> <brief_description> Adds a band limit filter to the Audio Bus. </brief_description> diff --git a/doc/classes/AudioEffectBandPassFilter.xml b/doc/classes/AudioEffectBandPassFilter.xml index cc8e351586..11aab3e86d 100644 --- a/doc/classes/AudioEffectBandPassFilter.xml +++ b/doc/classes/AudioEffectBandPassFilter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectBandPassFilter" inherits="AudioEffectFilter" category="Core" version="3.1-dev"> +<class name="AudioEffectBandPassFilter" inherits="AudioEffectFilter" category="Core" version="3.1"> <brief_description> Adds a band pass filter to the Audio Bus. </brief_description> diff --git a/doc/classes/AudioEffectChorus.xml b/doc/classes/AudioEffectChorus.xml index 6890fc92d9..43e14b3964 100644 --- a/doc/classes/AudioEffectChorus.xml +++ b/doc/classes/AudioEffectChorus.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectChorus" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectChorus" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Adds a chorus audio effect. </brief_description> diff --git a/doc/classes/AudioEffectCompressor.xml b/doc/classes/AudioEffectCompressor.xml index 33225a64ab..fa81bcf030 100644 --- a/doc/classes/AudioEffectCompressor.xml +++ b/doc/classes/AudioEffectCompressor.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectCompressor" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectCompressor" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Adds a Compressor audio effect to an Audio bus. Reduces sounds that exceed a certain threshold level, smooths out the dynamics and increases the overall volume. diff --git a/doc/classes/AudioEffectDelay.xml b/doc/classes/AudioEffectDelay.xml index 1c5757eca3..7c9d11111c 100644 --- a/doc/classes/AudioEffectDelay.xml +++ b/doc/classes/AudioEffectDelay.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectDelay" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectDelay" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Adds a Delay audio effect to an Audio bus. Plays input signal back after a period of time. Two tap delay and feedback options. diff --git a/doc/classes/AudioEffectDistortion.xml b/doc/classes/AudioEffectDistortion.xml index c33dced31e..74d12df554 100644 --- a/doc/classes/AudioEffectDistortion.xml +++ b/doc/classes/AudioEffectDistortion.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectDistortion" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectDistortion" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Adds a Distortion audio effect to an Audio bus. Modify the sound to make it dirty. diff --git a/doc/classes/AudioEffectEQ.xml b/doc/classes/AudioEffectEQ.xml index f6f44f2cb6..35a6f7557d 100644 --- a/doc/classes/AudioEffectEQ.xml +++ b/doc/classes/AudioEffectEQ.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectEQ" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectEQ" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Base class for audio equalizers. Gives you control over frequencies. Use it to create a custom equalizer if [AudioEffectEQ6], [AudioEffectEQ10] or [AudioEffectEQ21] don't fit your needs. diff --git a/doc/classes/AudioEffectEQ10.xml b/doc/classes/AudioEffectEQ10.xml index 201a26843c..f88a954417 100644 --- a/doc/classes/AudioEffectEQ10.xml +++ b/doc/classes/AudioEffectEQ10.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectEQ10" inherits="AudioEffectEQ" category="Core" version="3.1-dev"> +<class name="AudioEffectEQ10" inherits="AudioEffectEQ" category="Core" version="3.1"> <brief_description> Adds a 10-band equalizer audio effect to an Audio bus. Gives you control over frequencies from 31 Hz to 16000 Hz. Each frequency can be modulated between -60/+24 dB. diff --git a/doc/classes/AudioEffectEQ21.xml b/doc/classes/AudioEffectEQ21.xml index df0a536157..86d2189f27 100644 --- a/doc/classes/AudioEffectEQ21.xml +++ b/doc/classes/AudioEffectEQ21.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectEQ21" inherits="AudioEffectEQ" category="Core" version="3.1-dev"> +<class name="AudioEffectEQ21" inherits="AudioEffectEQ" category="Core" version="3.1"> <brief_description> Adds a 21-band equalizer audio effect to an Audio bus. Gives you control over frequencies from 22 Hz to 22000 Hz. Each frequency can be modulated between -60/+24 dB. diff --git a/doc/classes/AudioEffectEQ6.xml b/doc/classes/AudioEffectEQ6.xml index fe17a35d64..8f789cdbdd 100644 --- a/doc/classes/AudioEffectEQ6.xml +++ b/doc/classes/AudioEffectEQ6.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectEQ6" inherits="AudioEffectEQ" category="Core" version="3.1-dev"> +<class name="AudioEffectEQ6" inherits="AudioEffectEQ" category="Core" version="3.1"> <brief_description> Adds a 6-band equalizer audio effect to an Audio bus. Gives you control over frequencies from 32 Hz to 10000 Hz. Each frequency can be modulated between -60/+24 dB. diff --git a/doc/classes/AudioEffectFilter.xml b/doc/classes/AudioEffectFilter.xml index 75dc9b292d..5a86c092a0 100644 --- a/doc/classes/AudioEffectFilter.xml +++ b/doc/classes/AudioEffectFilter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectFilter" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectFilter" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Adds a filter to the Audio Bus. </brief_description> diff --git a/doc/classes/AudioEffectHighPassFilter.xml b/doc/classes/AudioEffectHighPassFilter.xml index 148ab83cb6..3d487fc783 100644 --- a/doc/classes/AudioEffectHighPassFilter.xml +++ b/doc/classes/AudioEffectHighPassFilter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectHighPassFilter" inherits="AudioEffectFilter" category="Core" version="3.1-dev"> +<class name="AudioEffectHighPassFilter" inherits="AudioEffectFilter" category="Core" version="3.1"> <brief_description> Adds a high pass filter to the Audio Bus. </brief_description> diff --git a/doc/classes/AudioEffectHighShelfFilter.xml b/doc/classes/AudioEffectHighShelfFilter.xml index e52578dc3a..ca2312ba6a 100644 --- a/doc/classes/AudioEffectHighShelfFilter.xml +++ b/doc/classes/AudioEffectHighShelfFilter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectHighShelfFilter" inherits="AudioEffectFilter" category="Core" version="3.1-dev"> +<class name="AudioEffectHighShelfFilter" inherits="AudioEffectFilter" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/AudioEffectLimiter.xml b/doc/classes/AudioEffectLimiter.xml index 6c61300e34..9e791f02d7 100644 --- a/doc/classes/AudioEffectLimiter.xml +++ b/doc/classes/AudioEffectLimiter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectLimiter" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectLimiter" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Adds a soft clip Limiter audio effect to an Audio bus. </brief_description> diff --git a/doc/classes/AudioEffectLowPassFilter.xml b/doc/classes/AudioEffectLowPassFilter.xml index cc357ae9ee..3facd8b665 100644 --- a/doc/classes/AudioEffectLowPassFilter.xml +++ b/doc/classes/AudioEffectLowPassFilter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectLowPassFilter" inherits="AudioEffectFilter" category="Core" version="3.1-dev"> +<class name="AudioEffectLowPassFilter" inherits="AudioEffectFilter" category="Core" version="3.1"> <brief_description> Adds a low pass filter to the Audio Bus. </brief_description> diff --git a/doc/classes/AudioEffectLowShelfFilter.xml b/doc/classes/AudioEffectLowShelfFilter.xml index be9bde1b69..aadbf30eaa 100644 --- a/doc/classes/AudioEffectLowShelfFilter.xml +++ b/doc/classes/AudioEffectLowShelfFilter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectLowShelfFilter" inherits="AudioEffectFilter" category="Core" version="3.1-dev"> +<class name="AudioEffectLowShelfFilter" inherits="AudioEffectFilter" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/AudioEffectNotchFilter.xml b/doc/classes/AudioEffectNotchFilter.xml index 7aec435bfa..741931f262 100644 --- a/doc/classes/AudioEffectNotchFilter.xml +++ b/doc/classes/AudioEffectNotchFilter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectNotchFilter" inherits="AudioEffectFilter" category="Core" version="3.1-dev"> +<class name="AudioEffectNotchFilter" inherits="AudioEffectFilter" category="Core" version="3.1"> <brief_description> Adds a notch filter to the Audio Bus. </brief_description> diff --git a/doc/classes/AudioEffectPanner.xml b/doc/classes/AudioEffectPanner.xml index a75918958e..cbd14de905 100644 --- a/doc/classes/AudioEffectPanner.xml +++ b/doc/classes/AudioEffectPanner.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectPanner" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectPanner" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Adds a Panner audio effect to an Audio bus. Pans sound left or right. </brief_description> diff --git a/doc/classes/AudioEffectPhaser.xml b/doc/classes/AudioEffectPhaser.xml index e276ed14b6..10566d089b 100644 --- a/doc/classes/AudioEffectPhaser.xml +++ b/doc/classes/AudioEffectPhaser.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectPhaser" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectPhaser" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Adds a Phaser audio effect to an Audio bus. Combines the original signal with a copy that is slightly out of phase with the original. diff --git a/doc/classes/AudioEffectPitchShift.xml b/doc/classes/AudioEffectPitchShift.xml index 4e4658580a..99095bae44 100644 --- a/doc/classes/AudioEffectPitchShift.xml +++ b/doc/classes/AudioEffectPitchShift.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectPitchShift" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectPitchShift" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Adds a Pitch shift audio effect to an Audio bus. Raises or lowers the pitch of original sound. diff --git a/doc/classes/AudioEffectReverb.xml b/doc/classes/AudioEffectReverb.xml index 8453e4b11b..fb2009105d 100644 --- a/doc/classes/AudioEffectReverb.xml +++ b/doc/classes/AudioEffectReverb.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectReverb" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectReverb" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> Adds a Reverb audio effect to an Audio bus. Simulates the sound of acoustic environments such as rooms, concert halls, caverns, or an open spaces. diff --git a/doc/classes/AudioEffectStereoEnhance.xml b/doc/classes/AudioEffectStereoEnhance.xml index 508dc96fb0..ae296d81a0 100644 --- a/doc/classes/AudioEffectStereoEnhance.xml +++ b/doc/classes/AudioEffectStereoEnhance.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioEffectStereoEnhance" inherits="AudioEffect" category="Core" version="3.1-dev"> +<class name="AudioEffectStereoEnhance" inherits="AudioEffect" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml index 9618f0b066..0be91427b1 100644 --- a/doc/classes/AudioServer.xml +++ b/doc/classes/AudioServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioServer" inherits="Object" category="Core" version="3.1-dev"> +<class name="AudioServer" inherits="Object" category="Core" version="3.1"> <brief_description> Server interface for low level audio access. </brief_description> diff --git a/doc/classes/AudioStream.xml b/doc/classes/AudioStream.xml index cbb16c3198..d332277248 100644 --- a/doc/classes/AudioStream.xml +++ b/doc/classes/AudioStream.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStream" inherits="Resource" category="Core" version="3.1-dev"> +<class name="AudioStream" inherits="Resource" category="Core" version="3.1"> <brief_description> Base class for audio streams. </brief_description> diff --git a/doc/classes/AudioStreamPlayback.xml b/doc/classes/AudioStreamPlayback.xml index a27ab1d3a2..0960935ad9 100644 --- a/doc/classes/AudioStreamPlayback.xml +++ b/doc/classes/AudioStreamPlayback.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamPlayback" inherits="Reference" category="Core" version="3.1-dev"> +<class name="AudioStreamPlayback" inherits="Reference" category="Core" version="3.1"> <brief_description> Meta class for playing back audio. </brief_description> diff --git a/doc/classes/AudioStreamPlayer.xml b/doc/classes/AudioStreamPlayer.xml index f7c8f76182..4a69695ae5 100644 --- a/doc/classes/AudioStreamPlayer.xml +++ b/doc/classes/AudioStreamPlayer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamPlayer" inherits="Node" category="Core" version="3.1-dev"> +<class name="AudioStreamPlayer" inherits="Node" category="Core" version="3.1"> <brief_description> Plays back audio. </brief_description> diff --git a/doc/classes/AudioStreamPlayer2D.xml b/doc/classes/AudioStreamPlayer2D.xml index 6594c9c8b9..495d37e6b8 100644 --- a/doc/classes/AudioStreamPlayer2D.xml +++ b/doc/classes/AudioStreamPlayer2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamPlayer2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="AudioStreamPlayer2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Plays audio in 2D. </brief_description> diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml index 7eb1ff2b91..3418ef7a26 100644 --- a/doc/classes/AudioStreamPlayer3D.xml +++ b/doc/classes/AudioStreamPlayer3D.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamPlayer3D" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="AudioStreamPlayer3D" inherits="Spatial" category="Core" version="3.1"> <brief_description> - Plays 3D sound in 3D space + Plays 3D sound in 3D space. </brief_description> <description> Plays a sound effect with directed sound effects, dampens with distance if needed, generates effect of hearable position in space. diff --git a/doc/classes/AudioStreamRandomPitch.xml b/doc/classes/AudioStreamRandomPitch.xml index 362504d00d..992c731d47 100644 --- a/doc/classes/AudioStreamRandomPitch.xml +++ b/doc/classes/AudioStreamRandomPitch.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamRandomPitch" inherits="AudioStream" category="Core" version="3.1-dev"> +<class name="AudioStreamRandomPitch" inherits="AudioStream" category="Core" version="3.1"> <brief_description> Plays audio with random pitch tweaking. </brief_description> diff --git a/doc/classes/AudioStreamSample.xml b/doc/classes/AudioStreamSample.xml index 224d1802dd..8b6651abe7 100644 --- a/doc/classes/AudioStreamSample.xml +++ b/doc/classes/AudioStreamSample.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamSample" inherits="AudioStream" category="Core" version="3.1-dev"> +<class name="AudioStreamSample" inherits="AudioStream" category="Core" version="3.1"> <brief_description> Plays audio. </brief_description> diff --git a/doc/classes/BackBufferCopy.xml b/doc/classes/BackBufferCopy.xml index 05a10da3ac..7070fdec4c 100644 --- a/doc/classes/BackBufferCopy.xml +++ b/doc/classes/BackBufferCopy.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BackBufferCopy" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="BackBufferCopy" inherits="Node2D" category="Core" version="3.1"> <brief_description> Copies a region of the screen (or the whole screen) to a buffer so it can be accessed with the texscreen() shader instruction. </brief_description> diff --git a/doc/classes/BakedLightmap.xml b/doc/classes/BakedLightmap.xml index 98ba28adeb..45c60302a6 100644 --- a/doc/classes/BakedLightmap.xml +++ b/doc/classes/BakedLightmap.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BakedLightmap" inherits="VisualInstance" category="Core" version="3.1-dev"> +<class name="BakedLightmap" inherits="VisualInstance" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/BakedLightmapData.xml b/doc/classes/BakedLightmapData.xml index 49f09dc32b..8ee10b0b8b 100644 --- a/doc/classes/BakedLightmapData.xml +++ b/doc/classes/BakedLightmapData.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BakedLightmapData" inherits="Resource" category="Core" version="3.1-dev"> +<class name="BakedLightmapData" inherits="Resource" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml index 0af7b6993c..2f44179adb 100644 --- a/doc/classes/BaseButton.xml +++ b/doc/classes/BaseButton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BaseButton" inherits="Control" category="Core" version="3.1-dev"> +<class name="BaseButton" inherits="Control" category="Core" version="3.1"> <brief_description> Base class for different kinds of buttons. </brief_description> diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml index 2bca7d7c1b..f7270fa5f9 100644 --- a/doc/classes/Basis.xml +++ b/doc/classes/Basis.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Basis" category="Built-In Types" version="3.1-dev"> +<class name="Basis" category="Built-In Types" version="3.1"> <brief_description> 3x3 matrix datatype. </brief_description> diff --git a/doc/classes/BitMap.xml b/doc/classes/BitMap.xml index 1d2fc950f0..98f554ebaa 100644 --- a/doc/classes/BitMap.xml +++ b/doc/classes/BitMap.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BitMap" inherits="Resource" category="Core" version="3.1-dev"> +<class name="BitMap" inherits="Resource" category="Core" version="3.1"> <brief_description> Boolean matrix. </brief_description> @@ -25,8 +25,10 @@ </return> <argument index="0" name="image" type="Image"> </argument> + <argument index="1" name="threshold" type="float" default="0.1"> + </argument> <description> - Creates a bitmap that matches the given image dimensions, every element of the bitmap is set to false if the alpha value of the image at that position is 0, and true in other case. + Creates a bitmap that matches the given image dimensions, every element of the bitmap is set to false if the alpha value of the image at that position is equal to [code]threshold[/code] or less, and true in other case. </description> </method> <method name="get_bit" qualifiers="const"> diff --git a/doc/classes/BitmapFont.xml b/doc/classes/BitmapFont.xml index cff8951a4c..c943caf636 100644 --- a/doc/classes/BitmapFont.xml +++ b/doc/classes/BitmapFont.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BitmapFont" inherits="Font" category="Core" version="3.1-dev"> +<class name="BitmapFont" inherits="Font" category="Core" version="3.1"> <brief_description> Renders text using [code]*.fnt[/code] fonts. </brief_description> diff --git a/doc/classes/BoneAttachment.xml b/doc/classes/BoneAttachment.xml index 3b7cd3fff2..a85453a415 100644 --- a/doc/classes/BoneAttachment.xml +++ b/doc/classes/BoneAttachment.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BoneAttachment" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="BoneAttachment" inherits="Spatial" category="Core" version="3.1"> <brief_description> A node that will attach to a bone. </brief_description> diff --git a/doc/classes/BoxContainer.xml b/doc/classes/BoxContainer.xml index 542703bae7..3fbad58a24 100644 --- a/doc/classes/BoxContainer.xml +++ b/doc/classes/BoxContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BoxContainer" inherits="Container" category="Core" version="3.1-dev"> +<class name="BoxContainer" inherits="Container" category="Core" version="3.1"> <brief_description> Base class for box containers. </brief_description> diff --git a/doc/classes/BoxShape.xml b/doc/classes/BoxShape.xml index 33ba197bec..d98a188870 100644 --- a/doc/classes/BoxShape.xml +++ b/doc/classes/BoxShape.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BoxShape" inherits="Shape" category="Core" version="3.1-dev"> +<class name="BoxShape" inherits="Shape" category="Core" version="3.1"> <brief_description> Box shape resource. </brief_description> diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml index 7783951cf9..382a538f2b 100644 --- a/doc/classes/Button.xml +++ b/doc/classes/Button.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Button" inherits="BaseButton" category="Core" version="3.1-dev"> +<class name="Button" inherits="BaseButton" category="Core" version="3.1"> <brief_description> Standard themed Button. </brief_description> diff --git a/doc/classes/ButtonGroup.xml b/doc/classes/ButtonGroup.xml index ebeb1e0aa0..e839c3e750 100644 --- a/doc/classes/ButtonGroup.xml +++ b/doc/classes/ButtonGroup.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ButtonGroup" inherits="Resource" category="Core" version="3.1-dev"> +<class name="ButtonGroup" inherits="Resource" category="Core" version="3.1"> <brief_description> Group of Buttons. </brief_description> diff --git a/doc/classes/Camera.xml b/doc/classes/Camera.xml index 226277d178..9451ee959f 100644 --- a/doc/classes/Camera.xml +++ b/doc/classes/Camera.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Camera" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="Camera" inherits="Spatial" category="Core" version="3.1"> <brief_description> Camera node, displays from a point of view. </brief_description> @@ -22,7 +22,7 @@ <return type="Transform"> </return> <description> - Get the camera transform. Subclassed cameras (such as CharacterCamera) may provide different transforms than the [Node] transform. + Gets the camera transform. Subclassed cameras (such as CharacterCamera) may provide different transforms than the [Node] transform. </description> </method> <method name="is_position_behind" qualifiers="const"> @@ -31,14 +31,14 @@ <argument index="0" name="world_point" type="Vector3"> </argument> <description> - Returns [code]true[/code] if the given position is behind the Camera. + Returns [code]true[/code] if the given position is behind the Camera. Note that a position which returns [code]false[/code] may still be outside the Camera's field of view. </description> </method> <method name="make_current"> <return type="void"> </return> <description> - Make this camera the current Camera for the [Viewport] (see class description). If the Camera Node is outside the scene tree, it will attempt to become current once it's added. + Makes this camera the current Camera for the [Viewport] (see class description). If the Camera Node is outside the scene tree, it will attempt to become current once it's added. </description> </method> <method name="project_local_ray_normal" qualifiers="const"> @@ -56,7 +56,7 @@ <argument index="0" name="screen_point" type="Vector2"> </argument> <description> - Returns how a 2D coordinate in the Viewport rectangle maps to a 3D point in worldspace. + Returns the 3D point in worldspace that maps to the given 2D coordinate in the [Viewport] rectangle. </description> </method> <method name="project_ray_normal" qualifiers="const"> @@ -87,7 +87,7 @@ <argument index="2" name="z_far" type="float"> </argument> <description> - Set the camera projection to orthogonal mode, by specifying a width and the [i]near[/i] and [i]far[/i] clip planes in worldspace units. (As a hint, 2D games often use this projection, with values specified in pixels) + Sets the camera projection to orthogonal mode, by specifying a width and the [i]near[/i] and [i]far[/i] clip planes in worldspace units. (As a hint, 2D games often use this projection, with values specified in pixels) </description> </method> <method name="set_perspective"> @@ -100,7 +100,7 @@ <argument index="2" name="z_far" type="float"> </argument> <description> - Set the camera projection to perspective mode, by specifying a [i]FOV[/i] Y angle in degrees (FOV means Field of View), and the [i]near[/i] and [i]far[/i] clip planes in worldspace units. + Sets the camera projection to perspective mode, by specifying a [i]FOV[/i] Y angle in degrees (FOV means Field of View), and the [i]near[/i] and [i]far[/i] clip planes in worldspace units. </description> </method> <method name="unproject_position" qualifiers="const"> @@ -109,7 +109,7 @@ <argument index="0" name="world_point" type="Vector3"> </argument> <description> - Returns how a 3D point in worldspace maps to a 2D coordinate in the [Viewport] rectangle. + Returns the 2D coordinate in the [Viewport] rectangle that maps to the given 3D point in worldspace. </description> </method> </methods> @@ -124,7 +124,7 @@ If not [code]DOPPLER_TRACKING_DISABLED[/code] this Camera will simulate the Doppler effect for objects changed in particular [code]_process[/code] methods. Default value: [code]DOPPLER_TRACKING_DISABLED[/code]. </member> <member name="environment" type="Environment" setter="set_environment" getter="get_environment"> - Set the [Environment] to use for this Camera. + The [Environment] to use for this Camera. </member> <member name="far" type="float" setter="set_zfar" getter="get_zfar"> The distance to the far culling boundary for this Camera relative to its local z-axis. @@ -133,10 +133,10 @@ The camera's field of view angle (in degrees). Only applicable in perspective mode. Since [member keep_aspect] locks one axis, [code]fov[/code] sets the other axis' field of view angle. </member> <member name="h_offset" type="float" setter="set_h_offset" getter="get_h_offset"> - The horizontal (X) offset of the Camear viewport. + The horizontal (X) offset of the Camera viewport. </member> <member name="keep_aspect" type="int" setter="set_keep_aspect_mode" getter="get_keep_aspect_mode" enum="Camera.KeepAspect"> - The axis to lock during [member fov]/[member size] adjustments. + The axis to lock during [member fov]/[member size] adjustments. Can be either [code]KEEP_WIDTH[/code] or [code]KEEP_HEIGHT[/code]. </member> <member name="near" type="float" setter="set_znear" getter="get_znear"> The distance to the near culling boundary for this Camera relative to its local z-axis. @@ -148,7 +148,7 @@ The camera's size measured as 1/2 the width or height. Only applicable in orthogonal mode. Since [member keep_aspect] locks on axis, [code]size[/code] sets the other axis' size length. </member> <member name="v_offset" type="float" setter="set_v_offset" getter="get_v_offset"> - The horizontal (Y) offset of the Camear viewport. + The vertical (Y) offset of the Camera viewport. </member> </members> <constants> diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml index 9ab1c63c1f..39cc1b84b3 100644 --- a/doc/classes/Camera2D.xml +++ b/doc/classes/Camera2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Camera2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="Camera2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Camera node for 2D scenes. </brief_description> diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index e3bf2b9577..1705808c04 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CanvasItem" inherits="Node" category="Core" version="3.1-dev"> +<class name="CanvasItem" inherits="Node" category="Core" version="3.1"> <brief_description> Base class of anything 2D. </brief_description> @@ -90,6 +90,18 @@ Draws a line from a 2D point to another, with a given color and width. It can be optionally antialiased. </description> </method> + <method name="draw_mesh"> + <return type="void"> + </return> + <argument index="0" name="mesh" type="Mesh"> + </argument> + <argument index="1" name="texture" type="Texture"> + </argument> + <argument index="2" name="normal_map" type="Texture" default="null"> + </argument> + <description> + </description> + </method> <method name="draw_multiline"> <return type="void"> </return> @@ -120,6 +132,18 @@ Draws multiple, parallel lines with a uniform [code]width[/code], segment-by-segment coloring, and optional antialiasing. Colors assigned to line segments match by index between [code]points[/code] and [code]colors[/code]. </description> </method> + <method name="draw_multimesh"> + <return type="void"> + </return> + <argument index="0" name="mesh" type="Mesh"> + </argument> + <argument index="1" name="texture" type="Texture"> + </argument> + <argument index="2" name="normal_map" type="Texture" default="null"> + </argument> + <description> + </description> + </method> <method name="draw_polygon"> <return type="void"> </return> diff --git a/doc/classes/CanvasItemMaterial.xml b/doc/classes/CanvasItemMaterial.xml index 1a2c61000e..fe7194dcfe 100644 --- a/doc/classes/CanvasItemMaterial.xml +++ b/doc/classes/CanvasItemMaterial.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CanvasItemMaterial" inherits="Material" category="Core" version="3.1-dev"> +<class name="CanvasItemMaterial" inherits="Material" category="Core" version="3.1"> <brief_description> A material for [CanvasItem]s. </brief_description> diff --git a/doc/classes/CanvasLayer.xml b/doc/classes/CanvasLayer.xml index d66ea5acdb..b2b0938822 100644 --- a/doc/classes/CanvasLayer.xml +++ b/doc/classes/CanvasLayer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CanvasLayer" inherits="Node" category="Core" version="3.1-dev"> +<class name="CanvasLayer" inherits="Node" category="Core" version="3.1"> <brief_description> Canvas drawing layer. </brief_description> diff --git a/doc/classes/CanvasModulate.xml b/doc/classes/CanvasModulate.xml index 1595b90ca5..7740423cf5 100644 --- a/doc/classes/CanvasModulate.xml +++ b/doc/classes/CanvasModulate.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CanvasModulate" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="CanvasModulate" inherits="Node2D" category="Core" version="3.1"> <brief_description> Tint the entire canvas. </brief_description> diff --git a/doc/classes/CapsuleMesh.xml b/doc/classes/CapsuleMesh.xml index 988c500d52..3500701290 100644 --- a/doc/classes/CapsuleMesh.xml +++ b/doc/classes/CapsuleMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CapsuleMesh" inherits="PrimitiveMesh" category="Core" version="3.1-dev"> +<class name="CapsuleMesh" inherits="PrimitiveMesh" category="Core" version="3.1"> <brief_description> Class representing a capsule-shaped [PrimitiveMesh]. </brief_description> diff --git a/doc/classes/CapsuleShape.xml b/doc/classes/CapsuleShape.xml index c0c5e4e1f2..0c00288783 100644 --- a/doc/classes/CapsuleShape.xml +++ b/doc/classes/CapsuleShape.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CapsuleShape" inherits="Shape" category="Core" version="3.1-dev"> +<class name="CapsuleShape" inherits="Shape" category="Core" version="3.1"> <brief_description> Capsule shape for collisions. </brief_description> diff --git a/doc/classes/CapsuleShape2D.xml b/doc/classes/CapsuleShape2D.xml index eaa7eef8cc..488c1ddc4f 100644 --- a/doc/classes/CapsuleShape2D.xml +++ b/doc/classes/CapsuleShape2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CapsuleShape2D" inherits="Shape2D" category="Core" version="3.1-dev"> +<class name="CapsuleShape2D" inherits="Shape2D" category="Core" version="3.1"> <brief_description> Capsule shape for 2D collisions. </brief_description> diff --git a/doc/classes/CenterContainer.xml b/doc/classes/CenterContainer.xml index fd2d8ee9e7..41c8cf7100 100644 --- a/doc/classes/CenterContainer.xml +++ b/doc/classes/CenterContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CenterContainer" inherits="Container" category="Core" version="3.1-dev"> +<class name="CenterContainer" inherits="Container" category="Core" version="3.1"> <brief_description> Keeps children controls centered. </brief_description> diff --git a/doc/classes/CheckBox.xml b/doc/classes/CheckBox.xml index f2aae0a674..fb2cf64d98 100644 --- a/doc/classes/CheckBox.xml +++ b/doc/classes/CheckBox.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CheckBox" inherits="Button" category="Core" version="3.1-dev"> +<class name="CheckBox" inherits="Button" category="Core" version="3.1"> <brief_description> - Binary choice user interface widget + Binary choice user interface widget. </brief_description> <description> A checkbox allows the user to make a binary choice (choosing only one of two possible options), for example Answer 'yes' or 'no'. diff --git a/doc/classes/CheckButton.xml b/doc/classes/CheckButton.xml index 1ad7f9cc68..deba9a17b6 100644 --- a/doc/classes/CheckButton.xml +++ b/doc/classes/CheckButton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CheckButton" inherits="Button" category="Core" version="3.1-dev"> +<class name="CheckButton" inherits="Button" category="Core" version="3.1"> <brief_description> Checkable button. </brief_description> diff --git a/doc/classes/CircleShape2D.xml b/doc/classes/CircleShape2D.xml index 8736cd47e5..db84c82e48 100644 --- a/doc/classes/CircleShape2D.xml +++ b/doc/classes/CircleShape2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CircleShape2D" inherits="Shape2D" category="Core" version="3.1-dev"> +<class name="CircleShape2D" inherits="Shape2D" category="Core" version="3.1"> <brief_description> Circular shape for 2D collisions. </brief_description> diff --git a/doc/classes/ClassDB.xml b/doc/classes/ClassDB.xml index 05f2f6472e..6b2c540c19 100644 --- a/doc/classes/ClassDB.xml +++ b/doc/classes/ClassDB.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ClassDB" inherits="Object" category="Core" version="3.1-dev"> +<class name="ClassDB" inherits="Object" category="Core" version="3.1"> <brief_description> Class information repository. </brief_description> diff --git a/doc/classes/CollisionObject.xml b/doc/classes/CollisionObject.xml index 8529c68b11..22b9725121 100644 --- a/doc/classes/CollisionObject.xml +++ b/doc/classes/CollisionObject.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CollisionObject" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="CollisionObject" inherits="Spatial" category="Core" version="3.1"> <brief_description> Base node for collision objects. </brief_description> diff --git a/doc/classes/CollisionObject2D.xml b/doc/classes/CollisionObject2D.xml index 2e361b5ac1..1ef72c0ca2 100644 --- a/doc/classes/CollisionObject2D.xml +++ b/doc/classes/CollisionObject2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CollisionObject2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="CollisionObject2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Base node for 2D collision objects. </brief_description> diff --git a/doc/classes/CollisionPolygon.xml b/doc/classes/CollisionPolygon.xml index b0f1142ac5..28e9ba4217 100644 --- a/doc/classes/CollisionPolygon.xml +++ b/doc/classes/CollisionPolygon.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CollisionPolygon" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="CollisionPolygon" inherits="Spatial" category="Core" version="3.1"> <brief_description> Editor-only class for defining a collision polygon in 3D space. </brief_description> diff --git a/doc/classes/CollisionPolygon2D.xml b/doc/classes/CollisionPolygon2D.xml index 8ef50cb4e0..5b940e7ff1 100644 --- a/doc/classes/CollisionPolygon2D.xml +++ b/doc/classes/CollisionPolygon2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CollisionPolygon2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="CollisionPolygon2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Defines a 2D collision polygon. </brief_description> diff --git a/doc/classes/CollisionShape.xml b/doc/classes/CollisionShape.xml index 7afd455ebd..95fa1175c3 100644 --- a/doc/classes/CollisionShape.xml +++ b/doc/classes/CollisionShape.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CollisionShape" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="CollisionShape" inherits="Spatial" category="Core" version="3.1"> <brief_description> Node that represents collision shape data in 3D space. </brief_description> <description> - Editor facility for creating and editing collision shapes in 3D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area] to give it a detection shape, or add it to a [PhysicsBody] to give create solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method get_shape] to get the actual shape. + Editor facility for creating and editing collision shapes in 3D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area] to give it a detection shape, or add it to a [PhysicsBody] to create a solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method get_shape] to get the actual shape. </description> <tutorials> http://docs.godotengine.org/en/3.0/tutorials/physics/physics_introduction.html diff --git a/doc/classes/CollisionShape2D.xml b/doc/classes/CollisionShape2D.xml index 7b3cddf4aa..3136f132bf 100644 --- a/doc/classes/CollisionShape2D.xml +++ b/doc/classes/CollisionShape2D.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CollisionShape2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="CollisionShape2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Node that represents collision shape data in 2D space. </brief_description> <description> - Editor facility for creating and editing collision shapes in 2D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area2D] to give it a detection shape, or add it to a [PhysicsBody2D] to give create solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method get_shape] to get the actual shape. + Editor facility for creating and editing collision shapes in 2D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area2D] to give it a detection shape, or add it to a [PhysicsBody2D] to create a solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method get_shape] to get the actual shape. </description> <tutorials> http://docs.godotengine.org/en/3.0/tutorials/physics/physics_introduction.html diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml index 8113ee3415..2617aaef17 100644 --- a/doc/classes/Color.xml +++ b/doc/classes/Color.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Color" category="Built-In Types" version="3.1-dev"> +<class name="Color" category="Built-In Types" version="3.1"> <brief_description> Color in RGBA format with some support for ARGB format. </brief_description> @@ -117,6 +117,24 @@ [/codeblock] </description> </method> + <method name="from_hsv"> + <return type="Color"> + </return> + <argument index="0" name="h" type="float"> + </argument> + <argument index="1" name="s" type="float"> + </argument> + <argument index="2" name="v" type="float"> + </argument> + <argument index="3" name="a" type="float" default="1"> + </argument> + <description> + Constructs a color from an HSV profile. [code]h[/code] is a value between 0 and 360. [code]s[/code] and [code]v[/code] are values between 0 and 1. + [codeblock] + var c = Color.from_hsv(210, 0.5, 0.79, 0.8) # equivalent to HSV(210, 50, 79, 0.8) or Color8(100, 151, 201, 0.8) + [/codeblock] + </description> + </method> <method name="gray"> <return type="float"> </return> diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml index a2b6e1ae04..2214264dca 100644 --- a/doc/classes/ColorPicker.xml +++ b/doc/classes/ColorPicker.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ColorPicker" inherits="BoxContainer" category="Core" version="3.1-dev"> +<class name="ColorPicker" inherits="BoxContainer" category="Core" version="3.1"> <brief_description> Color picker control. </brief_description> diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml index 227d979c64..eb86dc8af8 100644 --- a/doc/classes/ColorPickerButton.xml +++ b/doc/classes/ColorPickerButton.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ColorPickerButton" inherits="Button" category="Core" version="3.1-dev"> +<class name="ColorPickerButton" inherits="Button" category="Core" version="3.1"> <brief_description> - Button that pops out a [ColorPicker] + Button that pops out a [ColorPicker]. </brief_description> <description> Encapsulates a [ColorPicker] making it accesible by pressing a button, pressing the button will toggle the [ColorPicker] visibility diff --git a/doc/classes/ColorRect.xml b/doc/classes/ColorRect.xml index 468d9b0687..69a70cfa39 100644 --- a/doc/classes/ColorRect.xml +++ b/doc/classes/ColorRect.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ColorRect" inherits="Control" category="Core" version="3.1-dev"> +<class name="ColorRect" inherits="Control" category="Core" version="3.1"> <brief_description> Colored rect for canvas. </brief_description> diff --git a/doc/classes/ConcavePolygonShape.xml b/doc/classes/ConcavePolygonShape.xml index b838e21318..f4958d88d0 100644 --- a/doc/classes/ConcavePolygonShape.xml +++ b/doc/classes/ConcavePolygonShape.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ConcavePolygonShape" inherits="Shape" category="Core" version="3.1-dev"> +<class name="ConcavePolygonShape" inherits="Shape" category="Core" version="3.1"> <brief_description> Concave polygon shape. </brief_description> diff --git a/doc/classes/ConcavePolygonShape2D.xml b/doc/classes/ConcavePolygonShape2D.xml index 30dc887f3f..a653872353 100644 --- a/doc/classes/ConcavePolygonShape2D.xml +++ b/doc/classes/ConcavePolygonShape2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ConcavePolygonShape2D" inherits="Shape2D" category="Core" version="3.1-dev"> +<class name="ConcavePolygonShape2D" inherits="Shape2D" category="Core" version="3.1"> <brief_description> Concave polygon 2D shape resource for physics. </brief_description> diff --git a/doc/classes/ConeTwistJoint.xml b/doc/classes/ConeTwistJoint.xml index 93901dc3c4..d6b2f191a4 100644 --- a/doc/classes/ConeTwistJoint.xml +++ b/doc/classes/ConeTwistJoint.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ConeTwistJoint" inherits="Joint" category="Core" version="3.1-dev"> +<class name="ConeTwistJoint" inherits="Joint" category="Core" version="3.1"> <brief_description> - A twist joint between two 3D bodies + A twist joint between two 3D bodies. </brief_description> <description> The joint can rotate the bodies across an axis defined by the local x-axes of the [Joint]. diff --git a/doc/classes/ConfigFile.xml b/doc/classes/ConfigFile.xml index da86554380..a42d0f196e 100644 --- a/doc/classes/ConfigFile.xml +++ b/doc/classes/ConfigFile.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ConfigFile" inherits="Reference" category="Core" version="3.1-dev"> +<class name="ConfigFile" inherits="Reference" category="Core" version="3.1"> <brief_description> Helper class to handle INI-style files. </brief_description> <description> - This helper class can be used to store [Variant] values on the filesystem using INI-style formatting. The stored values are indentified by a section and a key: + This helper class can be used to store [Variant] values on the filesystem using INI-style formatting. The stored values are identified by a section and a key: [codeblock] [section] some_key=42 diff --git a/doc/classes/ConfirmationDialog.xml b/doc/classes/ConfirmationDialog.xml index 1641b5df6f..461f48420a 100644 --- a/doc/classes/ConfirmationDialog.xml +++ b/doc/classes/ConfirmationDialog.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ConfirmationDialog" inherits="AcceptDialog" category="Core" version="3.1-dev"> +<class name="ConfirmationDialog" inherits="AcceptDialog" category="Core" version="3.1"> <brief_description> Dialog for confirmation of actions. </brief_description> diff --git a/doc/classes/Container.xml b/doc/classes/Container.xml index b6afaa6bac..db365db233 100644 --- a/doc/classes/Container.xml +++ b/doc/classes/Container.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Container" inherits="Control" category="Core" version="3.1-dev"> +<class name="Container" inherits="Control" category="Core" version="3.1"> <brief_description> Base node for containers. </brief_description> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 46b2642b89..95e8622cf4 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Control" inherits="CanvasItem" category="Core" version="3.1-dev"> +<class name="Control" inherits="CanvasItem" category="Core" version="3.1"> <brief_description> All User Interface nodes inherit from Control. Features anchors and margins to adapt its position and size to its parent. </brief_description> @@ -117,6 +117,16 @@ <argument index="1" name="data" type="Variant"> </argument> <description> + Godot calls this method to test if [code]data[/code] from a control's [method get_drag_data] can be dropped at [code]position[/code]. [code]position[/code] is local to this control. + This method should only be used to test the data. Process the data in [method drop_data]. + [codeblock] + extends Control + + func can_drop_data(position, data): + # check position if it is relevant to you + # otherwise just check data + return typeof(data) == TYPE_DICTIONARY and data.has('expected') + [/codeblock] </description> </method> <method name="drop_data" qualifiers="virtual"> @@ -127,6 +137,16 @@ <argument index="1" name="data" type="Variant"> </argument> <description> + Godot calls this method to pass you the [code]data[/code] from a control's [method get_drag_data] result. Godot first calls [method can_drop_data] to test if [code]data[/code] is allowed to drop at [code]position[/code] where [code]position[/code] is local to this control. + [codeblock] + extends ColorRect + + func can_drop_data(position, data): + return typeof(data) == TYPE_DICTIONARY and data.has('color') + + func drop_data(position, data): + color = data['color'] + [/codeblock] </description> </method> <method name="force_drag"> @@ -137,6 +157,8 @@ <argument index="1" name="preview" type="Control"> </argument> <description> + Forces drag and bypasses [method get_drag_data] and [method set_drag_preview] by passing [code]data[/code] and [code]preview[/code]. Drag will start even if the mouse is neither over nor pressed on this control. + The methods [method can_drop_data] and [method drop_data] must be implemented on controls that want to receive drop data. </description> </method> <method name="get_begin" qualifiers="const"> @@ -186,6 +208,16 @@ <argument index="0" name="position" type="Vector2"> </argument> <description> + Godot calls this method to get data that can be dragged and dropped onto controls that expect drop data. Return null if there is no data to drag. Controls that want to receive drop data should implement [method can_drop_data] and [method drop_data]. [code]position[/code] is local to this control. Drag may be forced with [method force_drag]. + A preview that will follow the mouse that should represent the data can be set with [method set_drag_preview]. A good time to set the preview is in this method. + [codeblock] + extends Control + + func get_drag_data(position): + var mydata = make_data() + set_drag_preview(make_preview(mydata)) + return mydata + [/codeblock] </description> </method> <method name="get_end" qualifiers="const"> @@ -485,6 +517,28 @@ <argument index="0" name="target" type="Control"> </argument> <description> + Forwards the handling of this control's drag and drop to [code]target[/code] control. + Forwarding can be implemented in the target control similar to the methods [method get_drag_data], [method can_drop_data], and [method drop_data] but with two differences: + 1. The function name must be suffixed with [b]_fw[/b] + 2. The function must take an extra argument that is the control doing the forwarding + [codeblock] + # ThisControl.gd + extends Control + func _ready(): + set_drag_forwarding(target_control) + + # TargetControl.gd + extends Control + func can_drop_data_fw(position, data, from_control): + return true + + func drop_data_fw(position, data, from_control): + my_handle_data(data) + + func get_drag_data_fw(position, from_control): + set_drag_preview(my_preview) + return my_data() + [/codeblock] </description> </method> <method name="set_drag_preview"> @@ -493,6 +547,7 @@ <argument index="0" name="control" type="Control"> </argument> <description> + Shows the given control at the mouse pointer. A good time to call this method is in [method get_drag_data]. </description> </method> <method name="set_end"> diff --git a/doc/classes/ConvexPolygonShape.xml b/doc/classes/ConvexPolygonShape.xml index ac25fb8cb6..757b053ffe 100644 --- a/doc/classes/ConvexPolygonShape.xml +++ b/doc/classes/ConvexPolygonShape.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ConvexPolygonShape" inherits="Shape" category="Core" version="3.1-dev"> +<class name="ConvexPolygonShape" inherits="Shape" category="Core" version="3.1"> <brief_description> Convex polygon shape for 3D physics. </brief_description> diff --git a/doc/classes/ConvexPolygonShape2D.xml b/doc/classes/ConvexPolygonShape2D.xml index 3da9d28a8f..6b31149c2f 100644 --- a/doc/classes/ConvexPolygonShape2D.xml +++ b/doc/classes/ConvexPolygonShape2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ConvexPolygonShape2D" inherits="Shape2D" category="Core" version="3.1-dev"> +<class name="ConvexPolygonShape2D" inherits="Shape2D" category="Core" version="3.1"> <brief_description> Convex Polygon Shape for 2D physics. </brief_description> diff --git a/doc/classes/CubeMap.xml b/doc/classes/CubeMap.xml index edc4a165fc..ac5359738e 100644 --- a/doc/classes/CubeMap.xml +++ b/doc/classes/CubeMap.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CubeMap" inherits="Resource" category="Core" version="3.1-dev"> +<class name="CubeMap" inherits="Resource" category="Core" version="3.1"> <brief_description> A CubeMap is a 6 sided 3D texture. </brief_description> diff --git a/doc/classes/CubeMesh.xml b/doc/classes/CubeMesh.xml index e26e73e861..cef412bbde 100644 --- a/doc/classes/CubeMesh.xml +++ b/doc/classes/CubeMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CubeMesh" inherits="PrimitiveMesh" category="Core" version="3.1-dev"> +<class name="CubeMesh" inherits="PrimitiveMesh" category="Core" version="3.1"> <brief_description> Generate an axis-aligned cuboid [PrimitiveMesh]. </brief_description> diff --git a/doc/classes/Curve.xml b/doc/classes/Curve.xml index a430041571..c7f2f7bb8d 100644 --- a/doc/classes/Curve.xml +++ b/doc/classes/Curve.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Curve" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Curve" inherits="Resource" category="Core" version="3.1"> <brief_description> A mathematic curve. </brief_description> diff --git a/doc/classes/Curve2D.xml b/doc/classes/Curve2D.xml index c53f07d406..03db9c2ea1 100644 --- a/doc/classes/Curve2D.xml +++ b/doc/classes/Curve2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Curve2D" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Curve2D" inherits="Resource" category="Core" version="3.1"> <brief_description> Describes a Bezier curve in 2D space. </brief_description> diff --git a/doc/classes/Curve3D.xml b/doc/classes/Curve3D.xml index 1afa315465..f2308de12c 100644 --- a/doc/classes/Curve3D.xml +++ b/doc/classes/Curve3D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Curve3D" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Curve3D" inherits="Resource" category="Core" version="3.1"> <brief_description> Describes a Bezier curve in 3D space. </brief_description> diff --git a/doc/classes/CurveTexture.xml b/doc/classes/CurveTexture.xml index 67a21957ee..10e8a61f99 100644 --- a/doc/classes/CurveTexture.xml +++ b/doc/classes/CurveTexture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CurveTexture" inherits="Texture" category="Core" version="3.1-dev"> +<class name="CurveTexture" inherits="Texture" category="Core" version="3.1"> <brief_description> A texture that shows a curve. </brief_description> diff --git a/doc/classes/CylinderMesh.xml b/doc/classes/CylinderMesh.xml index 997180a17c..623830371a 100644 --- a/doc/classes/CylinderMesh.xml +++ b/doc/classes/CylinderMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CylinderMesh" inherits="PrimitiveMesh" category="Core" version="3.1-dev"> +<class name="CylinderMesh" inherits="PrimitiveMesh" category="Core" version="3.1"> <brief_description> Class representing a cylindrical [PrimitiveMesh]. </brief_description> diff --git a/doc/classes/DampedSpringJoint2D.xml b/doc/classes/DampedSpringJoint2D.xml index 55c6914c01..12e29cec32 100644 --- a/doc/classes/DampedSpringJoint2D.xml +++ b/doc/classes/DampedSpringJoint2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="DampedSpringJoint2D" inherits="Joint2D" category="Core" version="3.1-dev"> +<class name="DampedSpringJoint2D" inherits="Joint2D" category="Core" version="3.1"> <brief_description> Damped spring constraint for 2D physics. </brief_description> diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index c63e440a57..d7118265f1 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Dictionary" category="Built-In Types" version="3.1-dev"> +<class name="Dictionary" category="Built-In Types" version="3.1"> <brief_description> Dictionary type. </brief_description> diff --git a/doc/classes/DirectionalLight.xml b/doc/classes/DirectionalLight.xml index d777018ec9..5e492b74da 100644 --- a/doc/classes/DirectionalLight.xml +++ b/doc/classes/DirectionalLight.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="DirectionalLight" inherits="Light" category="Core" version="3.1-dev"> +<class name="DirectionalLight" inherits="Light" category="Core" version="3.1"> <brief_description> Directional Light, such as the Sun or the Moon. </brief_description> diff --git a/doc/classes/Directory.xml b/doc/classes/Directory.xml index 01590344cf..040ccf4462 100644 --- a/doc/classes/Directory.xml +++ b/doc/classes/Directory.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Directory" inherits="Reference" category="Core" version="3.1-dev"> +<class name="Directory" inherits="Reference" category="Core" version="3.1"> <brief_description> Type used to handle the filesystem. </brief_description> diff --git a/doc/classes/DynamicFont.xml b/doc/classes/DynamicFont.xml index a56a08e7f6..03752c6e89 100644 --- a/doc/classes/DynamicFont.xml +++ b/doc/classes/DynamicFont.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="DynamicFont" inherits="Font" category="Core" version="3.1-dev"> +<class name="DynamicFont" inherits="Font" category="Core" version="3.1"> <brief_description> DynamicFont renders vector font files at runtime. </brief_description> diff --git a/doc/classes/DynamicFontData.xml b/doc/classes/DynamicFontData.xml index 6113b0616b..7b34d02316 100644 --- a/doc/classes/DynamicFontData.xml +++ b/doc/classes/DynamicFontData.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="DynamicFontData" inherits="Resource" category="Core" version="3.1-dev"> +<class name="DynamicFontData" inherits="Resource" category="Core" version="3.1"> <brief_description> Used with [DynamicFont] to describe the location of a font file. </brief_description> @@ -16,7 +16,19 @@ <member name="font_path" type="String" setter="set_font_path" getter="get_font_path"> The path to the vector font file. </member> + <member name="hinting" type="int" setter="set_hinting" getter="get_hinting" enum="DynamicFontData.Hinting"> + The font hinting mode used by FreeType. + </member> </members> <constants> + <constant name="HINTING_NONE" value="0" enum="Hinting"> + Disable font hinting (smoother but less crisp). + </constant> + <constant name="HINTING_LIGHT" value="1" enum="Hinting"> + Use the light font hinting mode. + </constant> + <constant name="HINTING_NORMAL" value="2" enum="Hinting"> + Use the default font hinting mode (crisper but less smooth). + </constant> </constants> </class> diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml index 68999c2ae4..a6b72d08ff 100644 --- a/doc/classes/EditorExportPlugin.xml +++ b/doc/classes/EditorExportPlugin.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorExportPlugin" inherits="Reference" category="Core" version="3.1-dev"> +<class name="EditorExportPlugin" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/EditorFileDialog.xml b/doc/classes/EditorFileDialog.xml index da1dbb9327..fed9e264db 100644 --- a/doc/classes/EditorFileDialog.xml +++ b/doc/classes/EditorFileDialog.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorFileDialog" inherits="ConfirmationDialog" category="Core" version="3.1-dev"> +<class name="EditorFileDialog" inherits="ConfirmationDialog" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/EditorFileSystem.xml b/doc/classes/EditorFileSystem.xml index f5a3bf7eca..347acce2dd 100644 --- a/doc/classes/EditorFileSystem.xml +++ b/doc/classes/EditorFileSystem.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorFileSystem" inherits="Node" category="Core" version="3.1-dev"> +<class name="EditorFileSystem" inherits="Node" category="Core" version="3.1"> <brief_description> Resource filesystem, as the editor sees it. </brief_description> diff --git a/doc/classes/EditorFileSystemDirectory.xml b/doc/classes/EditorFileSystemDirectory.xml index 295a4d094f..f5d0471037 100644 --- a/doc/classes/EditorFileSystemDirectory.xml +++ b/doc/classes/EditorFileSystemDirectory.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorFileSystemDirectory" inherits="Object" category="Core" version="3.1-dev"> +<class name="EditorFileSystemDirectory" inherits="Object" category="Core" version="3.1"> <brief_description> A diretory for the resource filesystem. </brief_description> diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index fa22691a83..406bd7b7df 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorImportPlugin" inherits="Reference" category="Core" version="3.1-dev"> +<class name="EditorImportPlugin" inherits="Reference" category="Core" version="3.1"> <brief_description> Registers a custom resource importer in the editor. Use the class to parse any file and import it as a new resource type. </brief_description> diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml index 0731c332ad..006a7ca690 100644 --- a/doc/classes/EditorInterface.xml +++ b/doc/classes/EditorInterface.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorInterface" inherits="Node" category="Core" version="3.1-dev"> +<class name="EditorInterface" inherits="Node" category="Core" version="3.1"> <brief_description> Editor interface and main components. </brief_description> diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index b7f7d74f54..0a8d95d25d 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorPlugin" inherits="Node" category="Core" version="3.1-dev"> +<class name="EditorPlugin" inherits="Node" category="Core" version="3.1"> <brief_description> Used by the editor to extend its functionality. </brief_description> @@ -12,6 +12,17 @@ <demos> </demos> <methods> + <method name="add_autoload_singleton"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="path" type="String"> + </argument> + <description> + Add a script at [code]path[/code] to the Autoload list as [code]name[/code]. + </description> + </method> <method name="add_control_to_bottom_panel"> <return type="ToolButton"> </return> @@ -265,6 +276,15 @@ Queue save the project's editor layout. </description> </method> + <method name="remove_autoload_singleton"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + Remove an Autoload [code]name[/code] from the list. + </description> + </method> <method name="remove_control_from_bottom_panel"> <return type="void"> </return> diff --git a/doc/classes/EditorResourceConversionPlugin.xml b/doc/classes/EditorResourceConversionPlugin.xml index 240d82d5d2..ad0b7b0586 100644 --- a/doc/classes/EditorResourceConversionPlugin.xml +++ b/doc/classes/EditorResourceConversionPlugin.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorResourceConversionPlugin" inherits="Reference" category="Core" version="3.1-dev"> +<class name="EditorResourceConversionPlugin" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/EditorResourcePreview.xml b/doc/classes/EditorResourcePreview.xml index 6ec7f8a088..3b3e8a8369 100644 --- a/doc/classes/EditorResourcePreview.xml +++ b/doc/classes/EditorResourcePreview.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorResourcePreview" inherits="Node" category="Core" version="3.1-dev"> +<class name="EditorResourcePreview" inherits="Node" category="Core" version="3.1"> <brief_description> Helper to generate previews of resources or files. </brief_description> diff --git a/doc/classes/EditorResourcePreviewGenerator.xml b/doc/classes/EditorResourcePreviewGenerator.xml index 80aa185bb6..fb9af47b1f 100644 --- a/doc/classes/EditorResourcePreviewGenerator.xml +++ b/doc/classes/EditorResourcePreviewGenerator.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorResourcePreviewGenerator" inherits="Reference" category="Core" version="3.1-dev"> +<class name="EditorResourcePreviewGenerator" inherits="Reference" category="Core" version="3.1"> <brief_description> Custom generator of previews. </brief_description> diff --git a/doc/classes/EditorSceneImporter.xml b/doc/classes/EditorSceneImporter.xml index 340ea30ad0..6394dfdfe9 100644 --- a/doc/classes/EditorSceneImporter.xml +++ b/doc/classes/EditorSceneImporter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorSceneImporter" inherits="Reference" category="Core" version="3.1-dev"> +<class name="EditorSceneImporter" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/EditorScenePostImport.xml b/doc/classes/EditorScenePostImport.xml index 8e7c79db84..664ea33dd6 100644 --- a/doc/classes/EditorScenePostImport.xml +++ b/doc/classes/EditorScenePostImport.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorScenePostImport" inherits="Reference" category="Core" version="3.1-dev"> +<class name="EditorScenePostImport" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/EditorScript.xml b/doc/classes/EditorScript.xml index fa7a74460f..1c22095b37 100644 --- a/doc/classes/EditorScript.xml +++ b/doc/classes/EditorScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorScript" inherits="Reference" category="Core" version="3.1-dev"> +<class name="EditorScript" inherits="Reference" category="Core" version="3.1"> <brief_description> Base script that can be used to add extension functions to the editor. </brief_description> diff --git a/doc/classes/EditorSelection.xml b/doc/classes/EditorSelection.xml index 325fae0fe9..4edd8583a0 100644 --- a/doc/classes/EditorSelection.xml +++ b/doc/classes/EditorSelection.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorSelection" inherits="Object" category="Core" version="3.1-dev"> +<class name="EditorSelection" inherits="Object" category="Core" version="3.1"> <brief_description> Manages the SceneTree selection in the editor. </brief_description> diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index ef50c34792..cdd9560eda 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorSettings" inherits="Resource" category="Core" version="3.1-dev"> +<class name="EditorSettings" inherits="Resource" category="Core" version="3.1"> <brief_description> Object that holds the project-independent editor settings. </brief_description> diff --git a/doc/classes/EditorSpatialGizmo.xml b/doc/classes/EditorSpatialGizmo.xml index 3895f8a2e7..58d2671968 100644 --- a/doc/classes/EditorSpatialGizmo.xml +++ b/doc/classes/EditorSpatialGizmo.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EditorSpatialGizmo" inherits="SpatialGizmo" category="Core" version="3.1-dev"> +<class name="EditorSpatialGizmo" inherits="SpatialGizmo" category="Core" version="3.1"> <brief_description> Custom gizmo for editing Spatial objects. </brief_description> diff --git a/doc/classes/EncodedObjectAsID.xml b/doc/classes/EncodedObjectAsID.xml index 5b1b370fe0..8e6a117ea2 100644 --- a/doc/classes/EncodedObjectAsID.xml +++ b/doc/classes/EncodedObjectAsID.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="EncodedObjectAsID" inherits="Reference" category="Core" version="3.1-dev"> +<class name="EncodedObjectAsID" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index d4fb66540b..ea3c404346 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Engine" inherits="Object" category="Core" version="3.1-dev"> +<class name="Engine" inherits="Object" category="Core" version="3.1"> <brief_description> Access to basic engine properties. </brief_description> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index db87720e30..18adaa645c 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -1,11 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Environment" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Environment" inherits="Resource" category="Core" version="3.1"> <brief_description> Resource for environment nodes (like [WorldEnvironment]) that define multiple rendering options. </brief_description> <description> - Resource for environment nodes (like [WorldEnvironment]) that define multiple environment operations (such as background [Sky] or [Color], ambient light, fog, depth-of-field...). These parameters affect the final render of the scene. The order of these operations is: - - DOF Blur + Resource for environment nodes (like [WorldEnvironment]) that define multiple environment operations (such as background [Sky] or [Color], ambient light, fog, depth-of-field...). These parameters affect the final render of the scene. The order of these operations is: + + - DOF Blur - Motion Blur - Bloom - Tonemap (auto exposure) @@ -13,7 +14,7 @@ </description> <tutorials> http://docs.godotengine.org/en/3.0/tutorials/3d/environment_and_post_processing.html - http://docs.godotengine.org/en/3.0/tutorials/3d/high_dynamic_range.html + http://docs.godotengine.org/en/3.0/tutorials/3d/high_dynamic_range.html </tutorials> <demos> </demos> diff --git a/doc/classes/File.xml b/doc/classes/File.xml index baa7045e8c..534323348e 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="File" inherits="Reference" category="Core" version="3.1-dev"> +<class name="File" inherits="Reference" category="Core" version="3.1"> <brief_description> Type to handle file reading and writing operations. </brief_description> @@ -163,6 +163,20 @@ Returns a [String] saved in Pascal format from the file. </description> </method> + <method name="get_path"> + <return type="String"> + </return> + <description> + Returns the path as a [String] for the current open file. + </description> + </method> + <method name="get_path_absolute"> + <return type="String"> + </return> + <description> + Returns the absolute path as a [String] for the current open file. + </description> + </method> <method name="get_position" qualifiers="const"> <return type="int"> </return> @@ -380,7 +394,7 @@ <members> <member name="endian_swap" type="bool" setter="set_endian_swap" getter="get_endian_swap"> If [code]true[/code] the file's endianness is swapped. Use this if you're dealing with files written in big endian machines. - Note that this is about the file format, not CPU type. This is always reseted to [code]false[/code] whenever you open the file. + Note that this is about the file format, not CPU type. This is always reset to [code]false[/code] whenever you open the file. </member> </members> <constants> diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml index 50deecee72..b165d8fb8c 100644 --- a/doc/classes/FileDialog.xml +++ b/doc/classes/FileDialog.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="FileDialog" inherits="ConfirmationDialog" category="Core" version="3.1-dev"> +<class name="FileDialog" inherits="ConfirmationDialog" category="Core" version="3.1"> <brief_description> Dialog for selecting files or directories in the filesystem. </brief_description> diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml index a6ab2e3a77..376d234ec3 100644 --- a/doc/classes/Font.xml +++ b/doc/classes/Font.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Font" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Font" inherits="Resource" category="Core" version="3.1"> <brief_description> Internationalized font and text drawing support. </brief_description> diff --git a/doc/classes/FuncRef.xml b/doc/classes/FuncRef.xml index ff37408dcd..02b9dcfd88 100644 --- a/doc/classes/FuncRef.xml +++ b/doc/classes/FuncRef.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="FuncRef" inherits="Reference" category="Core" version="3.1-dev"> +<class name="FuncRef" inherits="Reference" category="Core" version="3.1"> <brief_description> Reference to a function in an object. </brief_description> diff --git a/doc/classes/GIProbe.xml b/doc/classes/GIProbe.xml index ffe01c37af..fde91d09ac 100644 --- a/doc/classes/GIProbe.xml +++ b/doc/classes/GIProbe.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GIProbe" inherits="VisualInstance" category="Core" version="3.1-dev"> +<class name="GIProbe" inherits="VisualInstance" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/GIProbeData.xml b/doc/classes/GIProbeData.xml index 97193600aa..b2186d7647 100644 --- a/doc/classes/GIProbeData.xml +++ b/doc/classes/GIProbeData.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GIProbeData" inherits="Resource" category="Core" version="3.1-dev"> +<class name="GIProbeData" inherits="Resource" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Generic6DOFJoint.xml b/doc/classes/Generic6DOFJoint.xml index ffcc6e2a0c..2aec6d7f4e 100644 --- a/doc/classes/Generic6DOFJoint.xml +++ b/doc/classes/Generic6DOFJoint.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Generic6DOFJoint" inherits="Joint" category="Core" version="3.1-dev"> +<class name="Generic6DOFJoint" inherits="Joint" category="Core" version="3.1"> <brief_description> The generic 6 degrees of freedom joint can implement a variety of joint-types by locking certain axes' rotation or translation. </brief_description> <description> - The first 3 dof axes are linear axes, which represent translation of Bodies, and the latter 3 dof axes represent the angular motion. Each axis can be either locked, or limited. + The first 3 DOF axes are linear axes, which represent translation of Bodies, and the latter 3 DOF axes represent the angular motion. Each axis can be either locked, or limited. </description> <tutorials> </tutorials> @@ -18,7 +18,7 @@ The lower, the longer an impulse from one side takes to travel to the other side. </member> <member name="angular_limit_x/enabled" type="bool" setter="set_flag_x" getter="get_flag_x"> - If [code]true[/code] rotation across the x-axis is enabled. + If [code]true[/code] rotation across the x-axis is limited. </member> <member name="angular_limit_x/erp" type="float" setter="set_param_x" getter="get_param_x"> When rotating across x-axis, this error tolerance factor defines how much the correction gets slowed down. The lower, the slower. @@ -42,7 +42,7 @@ The amount of rotational damping across the y-axis. The lower, the more dampening occurs. </member> <member name="angular_limit_y/enabled" type="bool" setter="set_flag_y" getter="get_flag_y"> - If [code]true[/code] rotation across the y-axis is enabled. + If [code]true[/code] rotation across the y-axis is limited. </member> <member name="angular_limit_y/erp" type="float" setter="set_param_y" getter="get_param_y"> When rotating across y-axis, this error tolerance factor defines how much the correction gets slowed down. The lower, the slower. @@ -66,7 +66,7 @@ The amount of rotational damping across the z-axis. The lower, the more dampening occurs. </member> <member name="angular_limit_z/enabled" type="bool" setter="set_flag_z" getter="get_flag_z"> - If [code]true[/code] rotation across the z-axis is enabled. + If [code]true[/code] rotation across the z-axis is limited. </member> <member name="angular_limit_z/erp" type="float" setter="set_param_z" getter="get_param_z"> When rotating across z-axis, this error tolerance factor defines how much the correction gets slowed down. The lower, the slower. @@ -117,7 +117,7 @@ The amount of damping that happens at the x-motion. </member> <member name="linear_limit_x/enabled" type="bool" setter="set_flag_x" getter="get_flag_x"> - If [code]true[/code] the linear motion across the x-axis is enabled. + If [code]true[/code] the linear motion across the x-axis is limited. </member> <member name="linear_limit_x/lower_distance" type="float" setter="set_param_x" getter="get_param_x"> The minimum difference between the pivot points' x-axis. @@ -135,7 +135,7 @@ The amount of damping that happens at the y-motion. </member> <member name="linear_limit_y/enabled" type="bool" setter="set_flag_y" getter="get_flag_y"> - If [code]true[/code] the linear motion across the y-axis is enabled. + If [code]true[/code] the linear motion across the y-axis is limited. </member> <member name="linear_limit_y/lower_distance" type="float" setter="set_param_y" getter="get_param_y"> The minimum difference between the pivot points' y-axis. @@ -153,7 +153,7 @@ The amount of damping that happens at the z-motion. </member> <member name="linear_limit_z/enabled" type="bool" setter="set_flag_z" getter="get_flag_z"> - If [code]true[/code] the linear motion across the z-axis is enabled. + If [code]true[/code] the linear motion across the z-axis is limited. </member> <member name="linear_limit_z/lower_distance" type="float" setter="set_param_z" getter="get_param_z"> The minimum difference between the pivot points' z-axis. diff --git a/doc/classes/Geometry.xml b/doc/classes/Geometry.xml index ad30829b5d..7b25f87b19 100644 --- a/doc/classes/Geometry.xml +++ b/doc/classes/Geometry.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Geometry" inherits="Object" category="Core" version="3.1-dev"> +<class name="Geometry" inherits="Object" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/GeometryInstance.xml b/doc/classes/GeometryInstance.xml index 3575754d51..aea1882dae 100644 --- a/doc/classes/GeometryInstance.xml +++ b/doc/classes/GeometryInstance.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GeometryInstance" inherits="VisualInstance" category="Core" version="3.1-dev"> +<class name="GeometryInstance" inherits="VisualInstance" category="Core" version="3.1"> <brief_description> Base node for geometry based visual instances. </brief_description> diff --git a/doc/classes/Gradient.xml b/doc/classes/Gradient.xml index 2a7e6e1de2..df4a507b65 100644 --- a/doc/classes/Gradient.xml +++ b/doc/classes/Gradient.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Gradient" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Gradient" inherits="Resource" category="Core" version="3.1"> <brief_description> Color interpolator node. </brief_description> diff --git a/doc/classes/GradientTexture.xml b/doc/classes/GradientTexture.xml index 483dee92b6..9d2465e23d 100644 --- a/doc/classes/GradientTexture.xml +++ b/doc/classes/GradientTexture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GradientTexture" inherits="Texture" category="Core" version="3.1-dev"> +<class name="GradientTexture" inherits="Texture" category="Core" version="3.1"> <brief_description> Gradient filled texture. </brief_description> diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index dde00f85da..5fb12612ab 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GraphEdit" inherits="Control" category="Core" version="3.1-dev"> +<class name="GraphEdit" inherits="Control" category="Core" version="3.1"> <brief_description> GraphEdit is an area capable of showing various GraphNodes. It manages connection events between them. </brief_description> diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index 6b581771e0..4c39720d69 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GraphNode" inherits="Container" category="Core" version="3.1-dev"> +<class name="GraphNode" inherits="Container" category="Core" version="3.1"> <brief_description> A GraphNode is a container with several input and output slots allowing connections between GraphNodes. Slots can have different, incompatible types. </brief_description> diff --git a/doc/classes/GridContainer.xml b/doc/classes/GridContainer.xml index 414b7c27e7..346ab9d357 100644 --- a/doc/classes/GridContainer.xml +++ b/doc/classes/GridContainer.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GridContainer" inherits="Container" category="Core" version="3.1-dev"> +<class name="GridContainer" inherits="Container" category="Core" version="3.1"> <brief_description> - Grid container used to arrange elements in a grid like layout + Grid container used to arrange elements in a grid like layout. </brief_description> <description> Grid container will arrange its children in a grid like structure, the grid columns are specified using the [method set_columns] method and the number of rows will be equal to the number of children in the container divided by the number of columns, for example: if the container has 5 children, and 2 columns, there will be 3 rows in the container. Notice that grid layout will preserve the columns and rows for every size of the container. diff --git a/doc/classes/GrooveJoint2D.xml b/doc/classes/GrooveJoint2D.xml index 30497d243e..a15c658f78 100644 --- a/doc/classes/GrooveJoint2D.xml +++ b/doc/classes/GrooveJoint2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GrooveJoint2D" inherits="Joint2D" category="Core" version="3.1-dev"> +<class name="GrooveJoint2D" inherits="Joint2D" category="Core" version="3.1"> <brief_description> Groove constraint for 2D physics. </brief_description> diff --git a/doc/classes/HBoxContainer.xml b/doc/classes/HBoxContainer.xml index 7c73583d58..9c86f17ef1 100644 --- a/doc/classes/HBoxContainer.xml +++ b/doc/classes/HBoxContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="HBoxContainer" inherits="BoxContainer" category="Core" version="3.1-dev"> +<class name="HBoxContainer" inherits="BoxContainer" category="Core" version="3.1"> <brief_description> Horizontal box container. </brief_description> diff --git a/doc/classes/HScrollBar.xml b/doc/classes/HScrollBar.xml index 20edc86747..61759c4f94 100644 --- a/doc/classes/HScrollBar.xml +++ b/doc/classes/HScrollBar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="HScrollBar" inherits="ScrollBar" category="Core" version="3.1-dev"> +<class name="HScrollBar" inherits="ScrollBar" category="Core" version="3.1"> <brief_description> Horizontal scroll bar. </brief_description> diff --git a/doc/classes/HSeparator.xml b/doc/classes/HSeparator.xml index e410aa4d86..1a9cf25857 100644 --- a/doc/classes/HSeparator.xml +++ b/doc/classes/HSeparator.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="HSeparator" inherits="Separator" category="Core" version="3.1-dev"> +<class name="HSeparator" inherits="Separator" category="Core" version="3.1"> <brief_description> Horizontal separator. </brief_description> diff --git a/doc/classes/HSlider.xml b/doc/classes/HSlider.xml index 70070d612b..6d5acded3c 100644 --- a/doc/classes/HSlider.xml +++ b/doc/classes/HSlider.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="HSlider" inherits="Slider" category="Core" version="3.1-dev"> +<class name="HSlider" inherits="Slider" category="Core" version="3.1"> <brief_description> Horizontal slider. </brief_description> diff --git a/doc/classes/HSplitContainer.xml b/doc/classes/HSplitContainer.xml index 7adf7d9d19..45b99c85a6 100644 --- a/doc/classes/HSplitContainer.xml +++ b/doc/classes/HSplitContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="HSplitContainer" inherits="SplitContainer" category="Core" version="3.1-dev"> +<class name="HSplitContainer" inherits="SplitContainer" category="Core" version="3.1"> <brief_description> Horizontal split container. </brief_description> diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml index 1c518fb6f5..5bd7c4cd3e 100644 --- a/doc/classes/HTTPClient.xml +++ b/doc/classes/HTTPClient.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="HTTPClient" inherits="Reference" category="Core" version="3.1-dev"> +<class name="HTTPClient" inherits="Reference" category="Core" version="3.1"> <brief_description> Hyper-text transfer protocol client. </brief_description> @@ -384,7 +384,7 @@ HTTP status code [code]429 Too Many Requests[/code]. The user has sent too many requests in a given amount of time (see "rate limiting"). Back off and increase time between requests or try again later. </constant> <constant name="RESPONSE_REQUEST_HEADER_FIELDS_TOO_LARGE" value="431" enum="ResponseCode"> - HTTP status code [code]431 Rquest Header Fields Too Large[/code]. The server is unwilling to process the request because its header fields are too large. The request MAY be resubmitted after reducing the size of the request header fields. + HTTP status code [code]431 Request Header Fields Too Large[/code]. The server is unwilling to process the request because its header fields are too large. The request MAY be resubmitted after reducing the size of the request header fields. </constant> <constant name="RESPONSE_UNAVAILABLE_FOR_LEGAL_REASONS" value="451" enum="ResponseCode"> HTTP status code [code]451 Response Unavailable For Legal Reasons[/code]. The server is denying access to the resource as a consequence of a legal demand. diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml index a6fd229ac9..010ef6d9d5 100644 --- a/doc/classes/HTTPRequest.xml +++ b/doc/classes/HTTPRequest.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="HTTPRequest" inherits="Node" category="Core" version="3.1-dev"> +<class name="HTTPRequest" inherits="Node" category="Core" version="3.1"> <brief_description> A node with the ability to send HTTP requests. </brief_description> diff --git a/doc/classes/HingeJoint.xml b/doc/classes/HingeJoint.xml index 01e88f1de6..3c5719056b 100644 --- a/doc/classes/HingeJoint.xml +++ b/doc/classes/HingeJoint.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="HingeJoint" inherits="Joint" category="Core" version="3.1-dev"> +<class name="HingeJoint" inherits="Joint" category="Core" version="3.1"> <brief_description> A hinge between two 3D bodies. </brief_description> diff --git a/doc/classes/IP.xml b/doc/classes/IP.xml index c8f2d3970b..bcb15e44fc 100644 --- a/doc/classes/IP.xml +++ b/doc/classes/IP.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="IP" inherits="Object" category="Core" version="3.1-dev"> +<class name="IP" inherits="Object" category="Core" version="3.1"> <brief_description> Internet protocol (IP) support functions like DNS resolution. </brief_description> diff --git a/doc/classes/IP_Unix.xml b/doc/classes/IP_Unix.xml index 7360067ecf..0dd4455562 100644 --- a/doc/classes/IP_Unix.xml +++ b/doc/classes/IP_Unix.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="IP_Unix" inherits="IP" category="Core" version="3.1-dev"> +<class name="IP_Unix" inherits="IP" category="Core" version="3.1"> <brief_description> Unix IP support. See [IP]. </brief_description> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index c4e0d55010..c1bd8d34eb 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Image" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Image" inherits="Resource" category="Core" version="3.1"> <brief_description> Image datatype. </brief_description> @@ -436,74 +436,109 @@ <constant name="FORMAT_LA8" value="1" enum="Format"> </constant> <constant name="FORMAT_R8" value="2" enum="Format"> + OpenGL texture format RED with a single component and a bitdepth of 8. </constant> <constant name="FORMAT_RG8" value="3" enum="Format"> + OpenGL texture format RG with two components and a bitdepth of 8 for each. </constant> <constant name="FORMAT_RGB8" value="4" enum="Format"> + OpenGL texture format RGB with three components, each with a bitdepth of 8. </constant> <constant name="FORMAT_RGBA8" value="5" enum="Format"> + OpenGL texture format RGBA with four components, each with a bitdepth of 8. </constant> <constant name="FORMAT_RGBA4444" value="6" enum="Format"> + OpenGL texture format RGBA with four components, each with a bitdepth of 4. </constant> <constant name="FORMAT_RGBA5551" value="7" enum="Format"> + OpenGL texture format GL_RGB5_A1 where 5 bits of depth for each component of RGB and one bit for alpha. </constant> <constant name="FORMAT_RF" value="8" enum="Format"> + OpenGL texture format GL_R32F where there's one component, a 32-bit floating-point value. </constant> <constant name="FORMAT_RGF" value="9" enum="Format"> + OpenGL texture format GL_RG32F where there are two components, each a 32-bit floating-point values. </constant> <constant name="FORMAT_RGBF" value="10" enum="Format"> + OpenGL texture format GL_RGB32F where there are three components, each a 32-bit floating-point values. </constant> <constant name="FORMAT_RGBAF" value="11" enum="Format"> + OpenGL texture format GL_RGBA32F where there are four components, each a 32-bit floating-point values. </constant> <constant name="FORMAT_RH" value="12" enum="Format"> + OpenGL texture format GL_R32F where there's one component, a 16-bit "half-precision" floating-point value. </constant> <constant name="FORMAT_RGH" value="13" enum="Format"> + OpenGL texture format GL_RG32F where there's two components, each a 16-bit "half-precision" floating-point value. </constant> <constant name="FORMAT_RGBH" value="14" enum="Format"> + OpenGL texture format GL_RGB32F where there's three components, each a 16-bit "half-precision" floating-point value. </constant> <constant name="FORMAT_RGBAH" value="15" enum="Format"> + OpenGL texture format GL_RGBA32F where there's four components, each a 16-bit "half-precision" floating-point value. </constant> <constant name="FORMAT_RGBE9995" value="16" enum="Format"> + A special OpenGL texture format where the three color components have 9 bits of precision and all three share a single exponent. </constant> <constant name="FORMAT_DXT1" value="17" enum="Format"> + The S3TC texture format that uses Block Compression 1, and is the smallest variation of S3TC, only providing 1 bit of alpha and color data being premultiplied with alpha. More information can be found at https://www.khronos.org/opengl/wiki/S3_Texture_Compression. </constant> <constant name="FORMAT_DXT3" value="18" enum="Format"> + The S3TC texture format that uses Block Compression 2, and color data is interpreted as not having been premultiplied by alpha. Well suited for images with sharp alpha transitions between translucent and opaque areas. </constant> <constant name="FORMAT_DXT5" value="19" enum="Format"> + The S3TC texture format also known as Block Compression 3 or BC3 that contains 64 bits of alpha channel data followed by 64 bits of DXT1-encoded color data. Color data is not premultiplied by alpha, same as DXT3. DXT5 generally produces superior results for transparency gradients than DXT3. </constant> <constant name="FORMAT_RGTC_R" value="20" enum="Format"> + Texture format that uses Red Green Texture Compression, normalizing the red channel data using the same compression algorithm that DXT5 uses for the alpha channel. More information can be found here https://www.khronos.org/opengl/wiki/Red_Green_Texture_Compression. </constant> <constant name="FORMAT_RGTC_RG" value="21" enum="Format"> + Texture format that uses Red Green Texture Compression, normalizing the red and green channel data using the same compression algorithm that DXT5 uses for the alpha channel. </constant> <constant name="FORMAT_BPTC_RGBA" value="22" enum="Format"> + Texture format that uses BPTC compression with unsigned normalized RGBA components. More information can be found at https://www.khronos.org/opengl/wiki/BPTC_Texture_Compression. </constant> <constant name="FORMAT_BPTC_RGBF" value="23" enum="Format"> + Texture format that uses BPTC compression with signed floating-point RGB components. </constant> <constant name="FORMAT_BPTC_RGBFU" value="24" enum="Format"> + Texture format that uses BPTC compression with unsigned floating-point RGB components. </constant> <constant name="FORMAT_PVRTC2" value="25" enum="Format"> + Texture format used on PowerVR-supported mobile platforms, uses 2 bit color depth with no alpha. More information on PVRTC can be found here https://en.wikipedia.org/wiki/PVRTC. </constant> <constant name="FORMAT_PVRTC2A" value="26" enum="Format"> + Same as PVRTC2, but with an alpha component. </constant> <constant name="FORMAT_PVRTC4" value="27" enum="Format"> + Similar to PVRTC2, but with 4 bit color depth and no alpha. </constant> <constant name="FORMAT_PVRTC4A" value="28" enum="Format"> + Same as PVRTC4, but with an alpha component. </constant> <constant name="FORMAT_ETC" value="29" enum="Format"> + Ericsson Texture Compression format, also referred to as 'ETC1', and is part of the OpenGL ES graphics standard. An overview of the format is given at https://en.wikipedia.org/wiki/Ericsson_Texture_Compression#ETC1. </constant> <constant name="FORMAT_ETC2_R11" value="30" enum="Format"> + Ericsson Texture Compression format 2 variant R11_EAC, which provides one channel of unsigned data. </constant> <constant name="FORMAT_ETC2_R11S" value="31" enum="Format"> + Ericsson Texture Compression format 2 variant SIGNED_R11_EAC, which provides one channel of signed data. </constant> <constant name="FORMAT_ETC2_RG11" value="32" enum="Format"> + Ericsson Texture Compression format 2 variant RG11_EAC, which provides two channels of unsigned data. </constant> <constant name="FORMAT_ETC2_RG11S" value="33" enum="Format"> + Ericsson Texture Compression format 2 variant SIGNED_RG11_EAC, which provides two channels of signed data. </constant> <constant name="FORMAT_ETC2_RGB8" value="34" enum="Format"> + Ericsson Texture Compression format 2 variant RGB8, which is a followup of ETC1 and compresses RGB888 data. </constant> <constant name="FORMAT_ETC2_RGBA8" value="35" enum="Format"> + Ericsson Texture Compression format 2 variant RGBA8, which compresses RGBA8888 data with full alpha support. </constant> <constant name="FORMAT_ETC2_RGB8A1" value="36" enum="Format"> + Ericsson Texture Compression format 2 variant RGB8_PUNCHTHROUGH_ALPHA1, which compresses RGBA data to make alpha either fully transparent or fully opaque. </constant> <constant name="FORMAT_MAX" value="37" enum="Format"> </constant> diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml index f7f211861d..9a5937299c 100644 --- a/doc/classes/ImageTexture.xml +++ b/doc/classes/ImageTexture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ImageTexture" inherits="Texture" category="Core" version="3.1-dev"> +<class name="ImageTexture" inherits="Texture" category="Core" version="3.1"> <brief_description> A [Texture] based on an [Image]. </brief_description> diff --git a/doc/classes/ImmediateGeometry.xml b/doc/classes/ImmediateGeometry.xml index 1cb86bc07f..29d05bf877 100644 --- a/doc/classes/ImmediateGeometry.xml +++ b/doc/classes/ImmediateGeometry.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ImmediateGeometry" inherits="GeometryInstance" category="Core" version="3.1-dev"> +<class name="ImmediateGeometry" inherits="GeometryInstance" category="Core" version="3.1"> <brief_description> Draws simple geometry from code. </brief_description> diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index 6ec6f08804..f3bff5a146 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Input" inherits="Object" category="Core" version="3.1-dev"> +<class name="Input" inherits="Object" category="Core" version="3.1"> <brief_description> A Singleton that deals with inputs. </brief_description> @@ -7,6 +7,7 @@ A Singleton that deals with inputs. This includes key presses, mouse buttons and movement, joypads, and input actions. Actions and their events can be set in the Project Settings / Input Map tab. Or be set with [InputMap]. </description> <tutorials> + http://docs.godotengine.org/en/3.0/tutorials/inputs/index.html </tutorials> <demos> </demos> @@ -44,7 +45,7 @@ <return type="Vector3"> </return> <description> - If the device has an accelerometer, this will return the movement. + If the device has an accelerometer, this will return the acceleration. Otherwise, it returns an empty [Vector3]. </description> </method> <method name="get_connected_joypads"> @@ -58,13 +59,14 @@ <return type="Vector3"> </return> <description> + If the device has an accelerometer, this will return the gravity. Otherwise, it returns an empty [Vector3]. </description> </method> <method name="get_gyroscope" qualifiers="const"> <return type="Vector3"> </return> <description> - If the device has a gyroscope, this will return the rate of rotation in rad/s around a device's x, y, and z axis. + If the device has a gyroscope, this will return the rate of rotation in rad/s around a device's x, y, and z axis. Otherwise, it returns an empty [Vector3]. </description> </method> <method name="get_joy_axis" qualifiers="const"> @@ -180,7 +182,8 @@ <argument index="0" name="action" type="String"> </argument> <description> - Returns [code]true[/code] when you start pressing the action event. + Returns [code]true[/code] when the user starts pressing the action event, meaning it's true only on the frame that the user pressed down the button. + This is useful for code that needs to run only once when an action is pressed, instead of every frame while it's pressed. </description> </method> <method name="is_action_just_released" qualifiers="const"> @@ -189,7 +192,7 @@ <argument index="0" name="action" type="String"> </argument> <description> - Returns [code]true[/code] when you stop pressing the action event. + Returns [code]true[/code] when the user stops pressing the action event, meaning it's true only on the frame that the user released the button. </description> </method> <method name="is_action_pressed" qualifiers="const"> @@ -259,6 +262,7 @@ <argument index="0" name="event" type="InputEvent"> </argument> <description> + Feeds an [InputEvent] to the game. Can be used to artificially trigger input events from code. </description> </method> <method name="remove_joy_mapping"> @@ -334,7 +338,7 @@ <argument index="1" name="connected" type="bool"> </argument> <description> - Emitted when a joypad device has been connected or disconnected + Emitted when a joypad device has been connected or disconnected. </description> </signal> </signals> @@ -349,40 +353,58 @@ Captures the mouse. The mouse will be hidden and unable to leave the game window. But it will still register movement and mouse button presses. </constant> <constant name="MOUSE_MODE_CONFINED" value="3" enum="MouseMode"> + Makes the mouse cursor visible but confines it to the game window. </constant> <constant name="CURSOR_ARROW" value="0" enum="CursorShape"> + Arrow cursor. Standard, default pointing cursor. </constant> <constant name="CURSOR_IBEAM" value="1" enum="CursorShape"> + I-beam cursor. Usually used to show where the text cursor will appear when the mouse is clicked. </constant> <constant name="CURSOR_POINTING_HAND" value="2" enum="CursorShape"> + Pointing hand cursor. Usually used to indicate the pointer is over a link or other interactable item. </constant> <constant name="CURSOR_CROSS" value="3" enum="CursorShape"> + Cross cursor. Typically appears over regions in which a drawing operation can be performance or for selections. </constant> <constant name="CURSOR_WAIT" value="4" enum="CursorShape"> + Wait cursor. Indicates that the application is busy performing an operation. </constant> <constant name="CURSOR_BUSY" value="5" enum="CursorShape"> + Busy cursor. See [code]CURSOR_WAIT[/code]. </constant> <constant name="CURSOR_DRAG" value="6" enum="CursorShape"> + Drag cursor. Usually displayed when dragging something. </constant> <constant name="CURSOR_CAN_DROP" value="7" enum="CursorShape"> + Can drop cursor. Usually displayed when dragging something to indicate that it can be dropped at the current position. </constant> <constant name="CURSOR_FORBIDDEN" value="8" enum="CursorShape"> + Forbidden cursor. Indicates that the current action is forbidden (for example, when dragging something) or that the control at a position is disabled. </constant> <constant name="CURSOR_VSIZE" value="9" enum="CursorShape"> + Vertical resize mouse cursor. A double headed vertical arrow. It tells the user they can resize the window or the panel vertically. </constant> <constant name="CURSOR_HSIZE" value="10" enum="CursorShape"> + Horizontal resize mouse cursor. A double headed horizontal arrow. It tells the user they can resize the window or the panel horizontally. </constant> <constant name="CURSOR_BDIAGSIZE" value="11" enum="CursorShape"> + Window resize mouse cursor. The cursor is a double headed arrow that goes from the bottom left to the top right. It tells the user they can resize the window or the panel both horizontally and vertically. </constant> <constant name="CURSOR_FDIAGSIZE" value="12" enum="CursorShape"> + Window resize mouse cursor. The cursor is a double headed arrow that goes from the top left to the bottom right, the opposite of [code]CURSOR_BDIAGSIZE[/code]. It tells the user they can resize the window or the panel both horizontally and vertically. </constant> <constant name="CURSOR_MOVE" value="13" enum="CursorShape"> + Move cursor. Indicates that something can be moved. </constant> <constant name="CURSOR_VSPLIT" value="14" enum="CursorShape"> + Vertical split mouse cursor. On Windows, it's the same as [code]CURSOR_VSIZE[/code]. </constant> <constant name="CURSOR_HSPLIT" value="15" enum="CursorShape"> + Horizontal split mouse cursor. On Windows, it's the same as [code]CURSOR_HSIZE[/code]. </constant> <constant name="CURSOR_HELP" value="16" enum="CursorShape"> + Help cursor. Usually a question mark. </constant> </constants> </class> diff --git a/doc/classes/InputDefault.xml b/doc/classes/InputDefault.xml index b82904c023..27bfff2e67 100644 --- a/doc/classes/InputDefault.xml +++ b/doc/classes/InputDefault.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputDefault" inherits="Input" category="Core" version="3.1-dev"> +<class name="InputDefault" inherits="Input" category="Core" version="3.1"> <brief_description> Default implementation of the [Input] class. </brief_description> diff --git a/doc/classes/InputEvent.xml b/doc/classes/InputEvent.xml index 41defdcb7f..b30b144614 100644 --- a/doc/classes/InputEvent.xml +++ b/doc/classes/InputEvent.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEvent" inherits="Resource" category="Core" version="3.1-dev"> +<class name="InputEvent" inherits="Resource" category="Core" version="3.1"> <brief_description> Generic input event </brief_description> diff --git a/doc/classes/InputEventAction.xml b/doc/classes/InputEventAction.xml index f0c6cf59be..e50c43c045 100644 --- a/doc/classes/InputEventAction.xml +++ b/doc/classes/InputEventAction.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventAction" inherits="InputEvent" category="Core" version="3.1-dev"> +<class name="InputEventAction" inherits="InputEvent" category="Core" version="3.1"> <brief_description> Input event type for actions. </brief_description> diff --git a/doc/classes/InputEventGesture.xml b/doc/classes/InputEventGesture.xml index 20410a8d5e..eb1e613b7c 100644 --- a/doc/classes/InputEventGesture.xml +++ b/doc/classes/InputEventGesture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventGesture" inherits="InputEventWithModifiers" category="Core" version="3.1-dev"> +<class name="InputEventGesture" inherits="InputEventWithModifiers" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/InputEventJoypadButton.xml b/doc/classes/InputEventJoypadButton.xml index 2c7c41d9e0..fdfdc10460 100644 --- a/doc/classes/InputEventJoypadButton.xml +++ b/doc/classes/InputEventJoypadButton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventJoypadButton" inherits="InputEvent" category="Core" version="3.1-dev"> +<class name="InputEventJoypadButton" inherits="InputEvent" category="Core" version="3.1"> <brief_description> Input event for gamepad buttons. </brief_description> diff --git a/doc/classes/InputEventJoypadMotion.xml b/doc/classes/InputEventJoypadMotion.xml index cdcab3fcab..001dce9a03 100644 --- a/doc/classes/InputEventJoypadMotion.xml +++ b/doc/classes/InputEventJoypadMotion.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventJoypadMotion" inherits="InputEvent" category="Core" version="3.1-dev"> +<class name="InputEventJoypadMotion" inherits="InputEvent" category="Core" version="3.1"> <brief_description> Input event type for gamepad joysticks and other motions. For buttons see [code]InputEventJoypadButton[/code]. </brief_description> diff --git a/doc/classes/InputEventKey.xml b/doc/classes/InputEventKey.xml index 1cd00e1042..dada5034f5 100644 --- a/doc/classes/InputEventKey.xml +++ b/doc/classes/InputEventKey.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventKey" inherits="InputEventWithModifiers" category="Core" version="3.1-dev"> +<class name="InputEventKey" inherits="InputEventWithModifiers" category="Core" version="3.1"> <brief_description> Input event type for keyboard events. </brief_description> diff --git a/doc/classes/InputEventMagnifyGesture.xml b/doc/classes/InputEventMagnifyGesture.xml index 06beaa84f9..e9a0149c56 100644 --- a/doc/classes/InputEventMagnifyGesture.xml +++ b/doc/classes/InputEventMagnifyGesture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventMagnifyGesture" inherits="InputEventGesture" category="Core" version="3.1-dev"> +<class name="InputEventMagnifyGesture" inherits="InputEventGesture" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/InputEventMouse.xml b/doc/classes/InputEventMouse.xml index 5d50d32d44..96a0116c3c 100644 --- a/doc/classes/InputEventMouse.xml +++ b/doc/classes/InputEventMouse.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventMouse" inherits="InputEventWithModifiers" category="Core" version="3.1-dev"> +<class name="InputEventMouse" inherits="InputEventWithModifiers" category="Core" version="3.1"> <brief_description> Base input event type for mouse events. </brief_description> diff --git a/doc/classes/InputEventMouseButton.xml b/doc/classes/InputEventMouseButton.xml index bbdd2aff4e..73190c7283 100644 --- a/doc/classes/InputEventMouseButton.xml +++ b/doc/classes/InputEventMouseButton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventMouseButton" inherits="InputEventMouse" category="Core" version="3.1-dev"> +<class name="InputEventMouseButton" inherits="InputEventMouse" category="Core" version="3.1"> <brief_description> Input event type for mouse button events. </brief_description> diff --git a/doc/classes/InputEventMouseMotion.xml b/doc/classes/InputEventMouseMotion.xml index 96160dc699..83aa28c693 100644 --- a/doc/classes/InputEventMouseMotion.xml +++ b/doc/classes/InputEventMouseMotion.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventMouseMotion" inherits="InputEventMouse" category="Core" version="3.1-dev"> +<class name="InputEventMouseMotion" inherits="InputEventMouse" category="Core" version="3.1"> <brief_description> Input event type for mouse motion events. </brief_description> diff --git a/doc/classes/InputEventPanGesture.xml b/doc/classes/InputEventPanGesture.xml index 06edf36d06..063986ae65 100644 --- a/doc/classes/InputEventPanGesture.xml +++ b/doc/classes/InputEventPanGesture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventPanGesture" inherits="InputEventGesture" category="Core" version="3.1-dev"> +<class name="InputEventPanGesture" inherits="InputEventGesture" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/InputEventScreenDrag.xml b/doc/classes/InputEventScreenDrag.xml index fd7ec15acc..a2ac8d587f 100644 --- a/doc/classes/InputEventScreenDrag.xml +++ b/doc/classes/InputEventScreenDrag.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventScreenDrag" inherits="InputEvent" category="Core" version="3.1-dev"> +<class name="InputEventScreenDrag" inherits="InputEvent" category="Core" version="3.1"> <brief_description> Input event type for screen drag events. (only available on mobile devices) diff --git a/doc/classes/InputEventScreenTouch.xml b/doc/classes/InputEventScreenTouch.xml index 019332ec26..64b9550f9d 100644 --- a/doc/classes/InputEventScreenTouch.xml +++ b/doc/classes/InputEventScreenTouch.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventScreenTouch" inherits="InputEvent" category="Core" version="3.1-dev"> +<class name="InputEventScreenTouch" inherits="InputEvent" category="Core" version="3.1"> <brief_description> Input event type for screen touch events. (only available on mobile devices) diff --git a/doc/classes/InputEventWithModifiers.xml b/doc/classes/InputEventWithModifiers.xml index a31df65ffb..2d046cbfd2 100644 --- a/doc/classes/InputEventWithModifiers.xml +++ b/doc/classes/InputEventWithModifiers.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputEventWithModifiers" inherits="InputEvent" category="Core" version="3.1-dev"> +<class name="InputEventWithModifiers" inherits="InputEvent" category="Core" version="3.1"> <brief_description> Base class for keys events with modifiers. </brief_description> diff --git a/doc/classes/InputMap.xml b/doc/classes/InputMap.xml index c5326c6211..eeb225d445 100644 --- a/doc/classes/InputMap.xml +++ b/doc/classes/InputMap.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InputMap" inherits="Object" category="Core" version="3.1-dev"> +<class name="InputMap" inherits="Object" category="Core" version="3.1"> <brief_description> Singleton that manages [InputEventAction]. </brief_description> diff --git a/doc/classes/InstancePlaceholder.xml b/doc/classes/InstancePlaceholder.xml index 834ad7bb11..5945e1068f 100644 --- a/doc/classes/InstancePlaceholder.xml +++ b/doc/classes/InstancePlaceholder.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InstancePlaceholder" inherits="Node" category="Core" version="3.1-dev"> +<class name="InstancePlaceholder" inherits="Node" category="Core" version="3.1"> <brief_description> Placeholder for the root [Node] of a [PackedScene]. </brief_description> <description> - Turning on the option [b]Load As Placeholder[/b] for an instanced scene in the editor causes it to be replaced by an InstacePlaceholder when running the game. This makes it possible to delay actually loading the scene until calling [method replace_by_instance]. This is useful to avoid loading large scenes all at once by loading parts of it selectively. + Turning on the option [b]Load As Placeholder[/b] for an instanced scene in the editor causes it to be replaced by an InstancePlaceholder when running the game. This makes it possible to delay actually loading the scene until calling [method replace_by_instance]. This is useful to avoid loading large scenes all at once by loading parts of it selectively. The InstancePlaceholder does not have a transform. This causes any child nodes to be positioned relatively to the Viewport from point (0,0), rather than their parent as displayed in the editor. Replacing the placeholder with a scene with a transform will transform children relatively to their parent again. </description> <tutorials> diff --git a/doc/classes/InterpolatedCamera.xml b/doc/classes/InterpolatedCamera.xml index 19252ca5a8..1ac7b5107e 100644 --- a/doc/classes/InterpolatedCamera.xml +++ b/doc/classes/InterpolatedCamera.xml @@ -1,8 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="InterpolatedCamera" inherits="Camera" category="Core" version="3.1-dev"> +<class name="InterpolatedCamera" inherits="Camera" category="Core" version="3.1"> <brief_description> + Camera which moves toward another node. </brief_description> <description> + InterpolatedCamera is a [Camera] which smoothly moves to match a target node's position and rotation. + If it is not [member enabled] or does not have a valid target set, InterpolatedCamera acts like a normal Camera. </description> <tutorials> </tutorials> @@ -15,15 +18,19 @@ <argument index="0" name="target" type="Object"> </argument> <description> + Sets the node to move toward and orient with. </description> </method> </methods> <members> <member name="enabled" type="bool" setter="set_interpolation_enabled" getter="is_interpolation_enabled"> + If [code]true[/code] and a target is set, the camera will move automatically. </member> <member name="speed" type="float" setter="set_speed" getter="get_speed"> + How quickly the camera moves toward its target. Higher values will result in tighter camera motion. </member> <member name="target" type="NodePath" setter="set_target_path" getter="get_target_path"> + The target's [NodePath]. </member> </members> <constants> diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index 95812ab299..e4db5aeb84 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ItemList" inherits="Control" category="Core" version="3.1-dev"> +<class name="ItemList" inherits="Control" category="Core" version="3.1"> <brief_description> Control that provides a list of selectable items (and/or icons) in a single column, or optionally in multiple columns. </brief_description> diff --git a/doc/classes/JSON.xml b/doc/classes/JSON.xml index d3c2e7bb2f..fbf9aea7f9 100644 --- a/doc/classes/JSON.xml +++ b/doc/classes/JSON.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="JSON" inherits="Object" category="Core" version="3.1-dev"> +<class name="JSON" inherits="Object" category="Core" version="3.1"> <brief_description> Helper class for parsing JSON data. </brief_description> diff --git a/doc/classes/JSONParseResult.xml b/doc/classes/JSONParseResult.xml index 4f9cdc976d..a9162e2d95 100644 --- a/doc/classes/JSONParseResult.xml +++ b/doc/classes/JSONParseResult.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="JSONParseResult" inherits="Reference" category="Core" version="3.1-dev"> +<class name="JSONParseResult" inherits="Reference" category="Core" version="3.1"> <brief_description> Data class wrapper for decoded JSON. </brief_description> diff --git a/doc/classes/JavaScript.xml b/doc/classes/JavaScript.xml index 4f37d75038..1d40b990a9 100644 --- a/doc/classes/JavaScript.xml +++ b/doc/classes/JavaScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="JavaScript" inherits="Object" category="Core" version="3.1-dev"> +<class name="JavaScript" inherits="Object" category="Core" version="3.1"> <brief_description> Singleton that connects the engine with the browser's JavaScript context in HTML5 export. </brief_description> diff --git a/doc/classes/Joint.xml b/doc/classes/Joint.xml index bb7ac74556..8cafdbdbf3 100644 --- a/doc/classes/Joint.xml +++ b/doc/classes/Joint.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Joint" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="Joint" inherits="Spatial" category="Core" version="3.1"> <brief_description> Base class for all 3D joints </brief_description> diff --git a/doc/classes/Joint2D.xml b/doc/classes/Joint2D.xml index a005e7994a..8247997927 100644 --- a/doc/classes/Joint2D.xml +++ b/doc/classes/Joint2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Joint2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="Joint2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Base node for all joint constraints in 2D physics. </brief_description> diff --git a/doc/classes/KinematicBody.xml b/doc/classes/KinematicBody.xml index 7ebea43cb9..5553602db2 100644 --- a/doc/classes/KinematicBody.xml +++ b/doc/classes/KinematicBody.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="KinematicBody" inherits="PhysicsBody" category="Core" version="3.1-dev"> +<class name="KinematicBody" inherits="PhysicsBody" category="Core" version="3.1"> <brief_description> Kinematic body 3D node. </brief_description> @@ -63,6 +63,8 @@ </return> <argument index="0" name="rel_vec" type="Vector3"> </argument> + <argument index="1" name="infinite_inertia" type="bool" default="true"> + </argument> <description> Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision], which contains information about the collision. </description> @@ -74,11 +76,13 @@ </argument> <argument index="1" name="floor_normal" type="Vector3" default="Vector3( 0, 0, 0 )"> </argument> - <argument index="2" name="slope_stop_min_velocity" type="float" default="0.05"> + <argument index="2" name="infinite_inertia" type="bool" default="true"> + </argument> + <argument index="3" name="slope_stop_min_velocity" type="float" default="0.05"> </argument> - <argument index="3" name="max_slides" type="int" default="4"> + <argument index="4" name="max_slides" type="int" default="4"> </argument> - <argument index="4" name="floor_max_angle" type="float" default="0.785398"> + <argument index="5" name="floor_max_angle" type="float" default="0.785398"> </argument> <description> Moves the body along a vector. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [code]KinematicBody[/code] or [RigidBody], it will also be affected by the motion of the other body. You can use this to make moving or rotating platforms, or to make nodes push other nodes. @@ -97,6 +101,8 @@ </argument> <argument index="1" name="rel_vec" type="Vector3"> </argument> + <argument index="2" name="infinite_inertia" type="bool"> + </argument> <description> Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would occur. </description> diff --git a/doc/classes/KinematicBody2D.xml b/doc/classes/KinematicBody2D.xml index da7b34440e..0448707c2e 100644 --- a/doc/classes/KinematicBody2D.xml +++ b/doc/classes/KinematicBody2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="KinematicBody2D" inherits="PhysicsBody2D" category="Core" version="3.1-dev"> +<class name="KinematicBody2D" inherits="PhysicsBody2D" category="Core" version="3.1"> <brief_description> Kinematic body 2D node. </brief_description> @@ -62,6 +62,8 @@ </return> <argument index="0" name="rel_vec" type="Vector2"> </argument> + <argument index="1" name="infinite_inertia" type="bool" default="true"> + </argument> <description> Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision2D], which contains information about the collision. </description> @@ -73,11 +75,13 @@ </argument> <argument index="1" name="floor_normal" type="Vector2" default="Vector2( 0, 0 )"> </argument> - <argument index="2" name="slope_stop_min_velocity" type="float" default="5"> + <argument index="2" name="infinite_inertia" type="bool" default="true"> + </argument> + <argument index="3" name="slope_stop_min_velocity" type="float" default="5"> </argument> - <argument index="3" name="max_bounces" type="int" default="4"> + <argument index="4" name="max_bounces" type="int" default="4"> </argument> - <argument index="4" name="floor_max_angle" type="float" default="0.785398"> + <argument index="5" name="floor_max_angle" type="float" default="0.785398"> </argument> <description> Moves the body along a vector. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [code]KinematicBody2D[/code] or [RigidBody2D], it will also be affected by the motion of the other body. You can use this to make moving or rotating platforms, or to make nodes push other nodes. @@ -96,6 +100,8 @@ </argument> <argument index="1" name="rel_vec" type="Vector2"> </argument> + <argument index="2" name="infinite_inertia" type="bool"> + </argument> <description> Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform2D], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would occur. </description> diff --git a/doc/classes/KinematicCollision.xml b/doc/classes/KinematicCollision.xml index 29025910f8..87eb9e77b5 100644 --- a/doc/classes/KinematicCollision.xml +++ b/doc/classes/KinematicCollision.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="KinematicCollision" inherits="Reference" category="Core" version="3.1-dev"> +<class name="KinematicCollision" inherits="Reference" category="Core" version="3.1"> <brief_description> Collision data for KinematicBody collisions. </brief_description> diff --git a/doc/classes/KinematicCollision2D.xml b/doc/classes/KinematicCollision2D.xml index b133703c65..e403ada0b9 100644 --- a/doc/classes/KinematicCollision2D.xml +++ b/doc/classes/KinematicCollision2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="KinematicCollision2D" inherits="Reference" category="Core" version="3.1-dev"> +<class name="KinematicCollision2D" inherits="Reference" category="Core" version="3.1"> <brief_description> Collision data for KinematicBody2D collisions. </brief_description> diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml index 7dd07c0c8e..24c28fc810 100644 --- a/doc/classes/Label.xml +++ b/doc/classes/Label.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Label" inherits="Control" category="Core" version="3.1-dev"> +<class name="Label" inherits="Control" category="Core" version="3.1"> <brief_description> Displays plain text in a line or wrapped inside a rectangle. For formatted text, use [RichTextLabel]. </brief_description> diff --git a/doc/classes/LargeTexture.xml b/doc/classes/LargeTexture.xml index f09f2aa82c..763b38f49e 100644 --- a/doc/classes/LargeTexture.xml +++ b/doc/classes/LargeTexture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="LargeTexture" inherits="Texture" category="Core" version="3.1-dev"> +<class name="LargeTexture" inherits="Texture" category="Core" version="3.1"> <brief_description> A Texture capable of storing many smaller Textures with offsets. </brief_description> diff --git a/doc/classes/Light.xml b/doc/classes/Light.xml index b99908256c..e05ed2d0b1 100644 --- a/doc/classes/Light.xml +++ b/doc/classes/Light.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Light" inherits="VisualInstance" category="Core" version="3.1-dev"> +<class name="Light" inherits="VisualInstance" category="Core" version="3.1"> <brief_description> Provides a base class for different kinds of light nodes. </brief_description> diff --git a/doc/classes/Light2D.xml b/doc/classes/Light2D.xml index b12cecacfc..f3903ffeae 100644 --- a/doc/classes/Light2D.xml +++ b/doc/classes/Light2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Light2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="Light2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Casts light in a 2D environment. </brief_description> diff --git a/doc/classes/LightOccluder2D.xml b/doc/classes/LightOccluder2D.xml index becfdd2ff2..38b9054411 100644 --- a/doc/classes/LightOccluder2D.xml +++ b/doc/classes/LightOccluder2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="LightOccluder2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="LightOccluder2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Occludes light cast by a Light2D, casting shadows. </brief_description> diff --git a/doc/classes/Line2D.xml b/doc/classes/Line2D.xml index fd45c8a986..19be34978d 100644 --- a/doc/classes/Line2D.xml +++ b/doc/classes/Line2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Line2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="Line2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> A 2D line. </brief_description> @@ -53,7 +53,7 @@ <argument index="1" name="position" type="Vector2"> </argument> <description> - Overwites the position in point [code]i[/code] with the supplied [code]position[/code]. + Overwrites the position in point [code]i[/code] with the supplied [code]position[/code]. </description> </method> </methods> diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index fa65180d89..b6adf84abd 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="LineEdit" inherits="Control" category="Core" version="3.1-dev"> +<class name="LineEdit" inherits="Control" category="Core" version="3.1"> <brief_description> Control that provides single line string editing. </brief_description> diff --git a/doc/classes/LineShape2D.xml b/doc/classes/LineShape2D.xml index 8ff3c71a9c..4a5486583a 100644 --- a/doc/classes/LineShape2D.xml +++ b/doc/classes/LineShape2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="LineShape2D" inherits="Shape2D" category="Core" version="3.1-dev"> +<class name="LineShape2D" inherits="Shape2D" category="Core" version="3.1"> <brief_description> Line shape for 2D collisions. </brief_description> diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml index b3a5f3fd7c..a09edfad89 100644 --- a/doc/classes/LinkButton.xml +++ b/doc/classes/LinkButton.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="LinkButton" inherits="BaseButton" category="Core" version="3.1-dev"> +<class name="LinkButton" inherits="BaseButton" category="Core" version="3.1"> <brief_description> - Simple button used to represent a link to some resource + Simple button used to represent a link to some resource. </brief_description> <description> This kind of buttons are primarily used when the interaction with the button causes a context change (like linking to a web page). diff --git a/doc/classes/Listener.xml b/doc/classes/Listener.xml index 0783c3ddba..720a7eafc5 100644 --- a/doc/classes/Listener.xml +++ b/doc/classes/Listener.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Listener" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="Listener" inherits="Spatial" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml index 214c2569e9..8c2aa01f81 100644 --- a/doc/classes/MainLoop.xml +++ b/doc/classes/MainLoop.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MainLoop" inherits="Object" category="Core" version="3.1-dev"> +<class name="MainLoop" inherits="Object" category="Core" version="3.1"> <brief_description> Main loop is the abstract main loop base class. </brief_description> diff --git a/doc/classes/MarginContainer.xml b/doc/classes/MarginContainer.xml index 80554192a0..15613e4bec 100644 --- a/doc/classes/MarginContainer.xml +++ b/doc/classes/MarginContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MarginContainer" inherits="Container" category="Core" version="3.1-dev"> +<class name="MarginContainer" inherits="Container" category="Core" version="3.1"> <brief_description> Simple margin container. </brief_description> diff --git a/doc/classes/Marshalls.xml b/doc/classes/Marshalls.xml index 44ff094971..687f81eec7 100644 --- a/doc/classes/Marshalls.xml +++ b/doc/classes/Marshalls.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Marshalls" inherits="Reference" category="Core" version="3.1-dev"> +<class name="Marshalls" inherits="Reference" category="Core" version="3.1"> <brief_description> Data transformation (marshalling) and encoding helpers. </brief_description> diff --git a/doc/classes/Material.xml b/doc/classes/Material.xml index fa53ce11da..7420a5deb0 100644 --- a/doc/classes/Material.xml +++ b/doc/classes/Material.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Material" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Material" inherits="Resource" category="Core" version="3.1"> <brief_description> Abstract base [Resource] for coloring and shading geometry. </brief_description> diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml index 333326b730..c9a8d3ce7a 100644 --- a/doc/classes/MenuButton.xml +++ b/doc/classes/MenuButton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MenuButton" inherits="Button" category="Core" version="3.1-dev"> +<class name="MenuButton" inherits="Button" category="Core" version="3.1"> <brief_description> Special button that brings up a [PopupMenu] when clicked. </brief_description> diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml index 6e60809999..83cadf959c 100644 --- a/doc/classes/Mesh.xml +++ b/doc/classes/Mesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Mesh" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Mesh" inherits="Resource" category="Core" version="3.1"> <brief_description> A [Resource] that contains vertex-array based geometry. </brief_description> diff --git a/doc/classes/MeshDataTool.xml b/doc/classes/MeshDataTool.xml index eff6bd2c61..43d94004a8 100644 --- a/doc/classes/MeshDataTool.xml +++ b/doc/classes/MeshDataTool.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MeshDataTool" inherits="Reference" category="Core" version="3.1-dev"> +<class name="MeshDataTool" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/MeshInstance.xml b/doc/classes/MeshInstance.xml index d70123239a..ef42726ca9 100644 --- a/doc/classes/MeshInstance.xml +++ b/doc/classes/MeshInstance.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MeshInstance" inherits="GeometryInstance" category="Core" version="3.1-dev"> +<class name="MeshInstance" inherits="GeometryInstance" category="Core" version="3.1"> <brief_description> Node that instances meshes into a scenario. </brief_description> diff --git a/doc/classes/MeshInstance2D.xml b/doc/classes/MeshInstance2D.xml new file mode 100644 index 0000000000..7f0136bf77 --- /dev/null +++ b/doc/classes/MeshInstance2D.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="MeshInstance2D" inherits="Node2D" category="Core" version="3.1"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <demos> + </demos> + <methods> + </methods> + <members> + <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh"> + </member> + <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map"> + </member> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/MeshLibrary.xml b/doc/classes/MeshLibrary.xml index 40776d095a..3726524638 100644 --- a/doc/classes/MeshLibrary.xml +++ b/doc/classes/MeshLibrary.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MeshLibrary" inherits="Resource" category="Core" version="3.1-dev"> +<class name="MeshLibrary" inherits="Resource" category="Core" version="3.1"> <brief_description> Library of meshes. </brief_description> diff --git a/doc/classes/MultiMesh.xml b/doc/classes/MultiMesh.xml index f5bd0885d3..b78d82199c 100644 --- a/doc/classes/MultiMesh.xml +++ b/doc/classes/MultiMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MultiMesh" inherits="Resource" category="Core" version="3.1-dev"> +<class name="MultiMesh" inherits="Resource" category="Core" version="3.1"> <brief_description> Provides high performance mesh instancing. </brief_description> diff --git a/doc/classes/MultiMeshInstance.xml b/doc/classes/MultiMeshInstance.xml index 0ffdb3c928..5e021dfe9b 100644 --- a/doc/classes/MultiMeshInstance.xml +++ b/doc/classes/MultiMeshInstance.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MultiMeshInstance" inherits="GeometryInstance" category="Core" version="3.1-dev"> +<class name="MultiMeshInstance" inherits="GeometryInstance" category="Core" version="3.1"> <brief_description> Node that instances a [MultiMesh]. </brief_description> diff --git a/doc/classes/Mutex.xml b/doc/classes/Mutex.xml index ce3a4cc45a..8f2751af98 100644 --- a/doc/classes/Mutex.xml +++ b/doc/classes/Mutex.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Mutex" inherits="Reference" category="Core" version="3.1-dev"> +<class name="Mutex" inherits="Reference" category="Core" version="3.1"> <brief_description> A synchronization Mutex. </brief_description> diff --git a/doc/classes/Navigation.xml b/doc/classes/Navigation.xml index e2be70979d..b3b9ada26c 100644 --- a/doc/classes/Navigation.xml +++ b/doc/classes/Navigation.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Navigation" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="Navigation" inherits="Spatial" category="Core" version="3.1"> <brief_description> A collection of [code]NavigationMesh[/code] resources and methods used for pathfinding. </brief_description> diff --git a/doc/classes/Navigation2D.xml b/doc/classes/Navigation2D.xml index 4709dab3e8..d2f4513372 100644 --- a/doc/classes/Navigation2D.xml +++ b/doc/classes/Navigation2D.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Navigation2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="Navigation2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> + Class to assist with character navigation and pathfinding. </brief_description> <description> </description> diff --git a/doc/classes/NavigationMesh.xml b/doc/classes/NavigationMesh.xml index 34ca1f852e..f0654e5b12 100644 --- a/doc/classes/NavigationMesh.xml +++ b/doc/classes/NavigationMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NavigationMesh" inherits="Resource" category="Core" version="3.1-dev"> +<class name="NavigationMesh" inherits="Resource" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/NavigationMeshInstance.xml b/doc/classes/NavigationMeshInstance.xml index 48b7e3a8ef..643bfc726f 100644 --- a/doc/classes/NavigationMeshInstance.xml +++ b/doc/classes/NavigationMeshInstance.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NavigationMeshInstance" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="NavigationMeshInstance" inherits="Spatial" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/NavigationPolygon.xml b/doc/classes/NavigationPolygon.xml index b8865a24b3..b29e19e5d8 100644 --- a/doc/classes/NavigationPolygon.xml +++ b/doc/classes/NavigationPolygon.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NavigationPolygon" inherits="Resource" category="Core" version="3.1-dev"> +<class name="NavigationPolygon" inherits="Resource" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/NavigationPolygonInstance.xml b/doc/classes/NavigationPolygonInstance.xml index db9b691ef1..ff95f652f1 100644 --- a/doc/classes/NavigationPolygonInstance.xml +++ b/doc/classes/NavigationPolygonInstance.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NavigationPolygonInstance" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="NavigationPolygonInstance" inherits="Node2D" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/NetworkedMultiplayerPeer.xml b/doc/classes/NetworkedMultiplayerPeer.xml index 794886dd64..71614c5f76 100644 --- a/doc/classes/NetworkedMultiplayerPeer.xml +++ b/doc/classes/NetworkedMultiplayerPeer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NetworkedMultiplayerPeer" inherits="PacketPeer" category="Core" version="3.1-dev"> +<class name="NetworkedMultiplayerPeer" inherits="PacketPeer" category="Core" version="3.1"> <brief_description> A high-level network interface to simplify multiplayer interactions. </brief_description> diff --git a/doc/classes/Nil.xml b/doc/classes/Nil.xml index 46c972d4d5..e09dba6511 100644 --- a/doc/classes/Nil.xml +++ b/doc/classes/Nil.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Nil" category="Built-In Types" version="3.1-dev"> +<class name="Nil" category="Built-In Types" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/NinePatchRect.xml b/doc/classes/NinePatchRect.xml index ce6fe26e07..f40b32951f 100644 --- a/doc/classes/NinePatchRect.xml +++ b/doc/classes/NinePatchRect.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NinePatchRect" inherits="Control" category="Core" version="3.1-dev"> +<class name="NinePatchRect" inherits="Control" category="Core" version="3.1"> <brief_description> Scalable texture-based frame that tiles the texture's centers and sides, but keeps the corners' original size. Perfect for panels and dialog boxes. </brief_description> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index e272e14d08..9129f64340 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Node" inherits="Object" category="Core" version="3.1-dev"> +<class name="Node" inherits="Object" category="Core" version="3.1"> <brief_description> Base class for all [i]scene[/i] objects. </brief_description> <description> Nodes are Godot's building blocks. They can be assigned as the child of another node, resulting in a tree arrangement. A given node can contain any number of nodes as children with the requirement that all siblings (direct children of a node) should have unique names. - A tree of nodes is called a [i]scene[/i]. Scenes can be saved to the disk and then instanced into other scenes. This allows for very high flexibility in the architecture and data model of Godot projects. Nodes can also optionally be added to groups. This makes it possible to access a number of nodes from code (an "enemies" group, for example) to perform grouped actions. + A tree of nodes is called a [i]scene[/i]. Scenes can be saved to the disk and then instanced into other scenes. This allows for very high flexibility in the architecture and data model of Godot projects. [b]Scene tree:[/b] The [SceneTree] contains the active tree of nodes. When a node is added to the scene tree, it receives the NOTIFICATION_ENTER_TREE notification and its [method _enter_tree] callback is triggered. Child nodes are always added [i]after[/i] their parent node, i.e. the [method _enter_tree] callback of a parent node will be triggered before its child's. Once all nodes have been added in the scene tree, they receive the NOTIFICATION_READY notification and their respective [method _ready] callbacks are triggered. For groups of nodes, the [method _ready] callback is called in reverse order, starting with the children and moving up to the parent nodes. This means that when adding a node to the scene tree, the following order will be used for the callbacks: [method _enter_tree] of the parent, [method _enter_tree] of the children, [method _ready] of the children and finally [method _ready] of the parent (recursively for the entire scene tree). @@ -13,7 +13,8 @@ Nodes can also process input events. When present, the [method _input] function will be called for each input that the program receives. In many cases, this can be overkill (unless used for simple projects), and the [method _unhandled_input] function might be preferred; it is called when the input event was not handled by anyone else (typically, GUI [Control] nodes), ensuring that the node only receives the events that were meant for it. To keep track of the scene hierarchy (especially when instancing scenes into other scenes), an "owner" can be set for the node with [method set_owner]. This keeps track of who instanced what. This is mostly useful when writing editors and tools, though. Finally, when a node is freed with [method free] or [method queue_free], it will also free all its children. - [b]Networking with nodes:[/b] After connecting to a server (or making one, see [NetworkedMultiplayerENet]) it is possible to use the built-in RPC (remote procedure call) system to communicate over the network. By calling [method rpc] with a method name, it will be called locally and in all connected peers (peers = clients and the server that accepts connections), with behaviour varying depending on the network mode ([method set_network_mode]) of the receiving peer. To identify which node receives the RPC call Godot will use its [NodePath] (make sure node names are the same on all peers). + [b]Groups:[/b] Nodes can be added to as many groups as you want to be easy to manage, you could create groups like "enemies" or "collectables" for example, depending on your game. See [method add_to_group], [method is_in_group] and [method remove_from_group]. You can then retrieve all nodes in these groups, iterate them and even call methods on groups via the methods on [SceneTree]. + [b]Networking with nodes:[/b] After connecting to a server (or making one, see [NetworkedMultiplayerENet]) it is possible to use the built-in RPC (remote procedure call) system to communicate over the network. By calling [method rpc] with a method name, it will be called locally and in all connected peers (peers = clients and the server that accepts connections). To identify which node receives the RPC call Godot will use its [NodePath] (make sure node names are the same on all peers). Also take a look at the high-level networking tutorial and corresponding demos. </description> <tutorials> http://docs.godotengine.org/en/3.0/getting_started/step_by_step/scenes_and_nodes.html @@ -45,6 +46,8 @@ <description> Called when there is an input event. The input event propagates through the node tree until a node consumes it. It is only called if input processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_input]. + To consume the input event and stop it propagating further to other nodes, [method SceneTree.set_input_as_handled] can be called. + For gameplay input, [method _unhandled_input] and [method _unhandled_key_input] are usually a better fit as they allow the GUI to intercept the events first. </description> </method> <method name="_physics_process" qualifiers="virtual"> @@ -74,7 +77,8 @@ </return> <description> Called when the node is "ready", i.e. when both the node and its children have entered the scene tree. If the node has children, their [method _ready] callbacks get triggered first, and the parent node will receive the ready notification afterwards. - Corresponds to the NOTIFICATION_READY notification in [method Object._notification]. + Corresponds to the NOTIFICATION_READY notification in [method Object._notification]. See also the [code]onready[/code] keyword for variables. + Usually used for initialization. For even earlier initialization, [method Object._init] may be used. Also see [method _enter_tree]. </description> </method> <method name="_unhandled_input" qualifiers="virtual"> @@ -83,8 +87,10 @@ <argument index="0" name="event" type="InputEvent"> </argument> <description> - Propagated to all nodes when the previous InputEvent is not consumed by any nodes. + Propagated to all nodes when the previous [InputEvent] is not consumed by any nodes. It is only called if unhandled input processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_unhandled_input]. + To consume the input event and stop it propagating further to other nodes, [method SceneTree.set_input_as_handled] can be called. + For gameplay input, this and [method _unhandled_key_input] are usually a better fit than [method _input] as they allow the GUI to intercept the events first. </description> </method> <method name="_unhandled_key_input" qualifiers="virtual"> @@ -93,6 +99,10 @@ <argument index="0" name="event" type="InputEventKey"> </argument> <description> + Propagated to all nodes when the previous [InputEventKey] is not consumed by any nodes. + It is only called if unhandled key input processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_unhandled_key_input]. + To consume the input event and stop it propagating further to other nodes, [method SceneTree.set_input_as_handled] can be called. + For gameplay input, this and [method _unhandled_input] are usually a better fit than [method _input] as they allow the GUI to intercept the events first. </description> </method> <method name="add_child"> @@ -129,7 +139,7 @@ <argument index="1" name="persistent" type="bool" default="false"> </argument> <description> - Adds the node to a group. Groups are helpers to name and organize a subset of nodes, for example "enemies" or "collectables". A node can be in any number of groups. Nodes can be assigned a group at any time, but will not be added until they are inside the scene tree (see [method is_inside_tree]). + Adds the node to a group. Groups are helpers to name and organize a subset of nodes, for example "enemies" or "collectables". A node can be in any number of groups. Nodes can be assigned a group at any time, but will not be added until they are inside the scene tree (see [method is_inside_tree]). See notes in the description, and the group methods in [SceneTree]. </description> </method> <method name="can_process" qualifiers="const"> @@ -203,7 +213,7 @@ <return type="int"> </return> <description> - Returns the peer ID of the network master for this node. + Returns the peer ID of the network master for this node. See [method set_network_master]. </description> </method> <method name="get_node" qualifiers="const"> @@ -262,7 +272,7 @@ <argument index="0" name="node" type="Node"> </argument> <description> - Returns the relative path from the current node to the specified node in "node" argument. Both nodes must be in the same scene, or the function will fail. + Returns the relative [NodePath] from this node to the specified [code]node[/code]. Both nodes must be in the same scene or the function will fail. </description> </method> <method name="get_physics_process_delta_time" qualifiers="const"> @@ -290,6 +300,7 @@ <return type="bool"> </return> <description> + Returns [code]true[/code] if this is an instance load placeholder. See [InstancePlaceholder]. </description> </method> <method name="get_tree" qualifiers="const"> @@ -354,7 +365,7 @@ <argument index="0" name="group" type="String"> </argument> <description> - Returns [code]true[/code] if this node is in the specified group. + Returns [code]true[/code] if this node is in the specified group. See notes in the description, and the group methods in [SceneTree]. </description> </method> <method name="is_inside_tree" qualifiers="const"> @@ -368,6 +379,7 @@ <return type="bool"> </return> <description> + Returns [code]true[/code] if the local system is the master of this node. </description> </method> <method name="is_physics_processing" qualifiers="const"> @@ -381,6 +393,7 @@ <return type="bool"> </return> <description> + Returns [code]true[/code] if internal physics processing is enabled (see [method set_physics_process_internal]). </description> </method> <method name="is_processing" qualifiers="const"> @@ -401,6 +414,7 @@ <return type="bool"> </return> <description> + Returns [code]true[/code] if internal processing is enabled (see [method set_process_internal]). </description> </method> <method name="is_processing_unhandled_input" qualifiers="const"> @@ -432,13 +446,14 @@ <return type="void"> </return> <description> + Prints all stray nodes (nodes outside the [SceneTree]). Used for debugging. Works only in debug builds. </description> </method> <method name="print_tree"> <return type="void"> </return> <description> - Prints the scene to stdout. Used mainly for debugging purposes. + Prints the scene hierarchy of this node and all it's children to stdout. Used mainly for debugging purposes. </description> </method> <method name="propagate_call"> @@ -499,7 +514,7 @@ <argument index="0" name="group" type="String"> </argument> <description> - Removes a node from a group. + Removes a node from a group. See notes in the description, and the group methods in [SceneTree]. </description> </method> <method name="replace_by"> @@ -526,7 +541,7 @@ <argument index="0" name="method" type="String"> </argument> <description> - Sends a remote procedure call request to all peers on the network (and locally), optionally sending additional data as arguments. Call request will be received by nodes with the same [NodePath]. + Sends a remote procedure call request for the given [code]method[/code] to peers on the network (and locally), optionally sending all additional arguments as arguments to the method called by the RPC. The call request will only be received by nodes with the same [NodePath], including the exact same node name. Behaviour depends on the RPC configuration for the given method, see [method rpc_config]. Methods are not exposed to RPCs by default. Also see [method rset] and [method rset_config] for properties. Returns an empty [Variant]. Note that you can only safely use RPCs on clients after you received the [code]connected_to_server[/code] signal from the [SceneTree]. You also need to keep track of the connection state, either by the [SceneTree] signals like [code]server_disconnected[/code] or by checking [code]SceneTree.network_peer.get_connection_status() == CONNECTION_CONNECTED[/code]. </description> </method> <method name="rpc_config"> @@ -537,7 +552,7 @@ <argument index="1" name="mode" type="int" enum="Node.RPCMode"> </argument> <description> - Changes the method's RPC mode (one of RPC_MODE_* constants). + Changes the RPC mode for the given [code]method[/code] to the given [code]mode[/code]. See [enum RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]sync[/code], [code]master[/code], [code]slave[/code]). By default, methods are not exposed to networking (and RPCs). Also see [method rset] and [method rset_config] for properties. </description> </method> <method name="rpc_id" qualifiers="vararg"> @@ -548,7 +563,7 @@ <argument index="1" name="method" type="String"> </argument> <description> - Sends a [method rpc] to a specific peer identified by [i]peer_id[/i]. + Sends a [method rpc] to a specific peer identified by [code]peer_id[/code]. Returns an empty [Variant]. </description> </method> <method name="rpc_unreliable" qualifiers="vararg"> @@ -557,7 +572,7 @@ <argument index="0" name="method" type="String"> </argument> <description> - Sends a [method rpc] using an unreliable protocol. + Sends a [method rpc] using an unreliable protocol. Returns an empty [Variant]. </description> </method> <method name="rpc_unreliable_id" qualifiers="vararg"> @@ -568,7 +583,7 @@ <argument index="1" name="method" type="String"> </argument> <description> - Sends a [method rpc] to a specific peer identified by [i]peer_id[/i] using an unreliable protocol. + Sends a [method rpc] to a specific peer identified by [code]peer_id[/code] using an unreliable protocol. Returns an empty [Variant]. </description> </method> <method name="rset"> @@ -579,7 +594,7 @@ <argument index="1" name="value" type="Variant"> </argument> <description> - Remotely changes property's value on other peers (and locally). + Remotely changes a property's value on other peers (and locally). Behaviour depends on the RPC configuration for the given property, see [method rset_config]. Also see [method rpc] for RPCs for methods, most information applies to this method as well. </description> </method> <method name="rset_config"> @@ -590,7 +605,7 @@ <argument index="1" name="mode" type="int" enum="Node.RPCMode"> </argument> <description> - Changes the property's RPC mode (one of RPC_MODE_* constants). + Changes the RPC mode for the given [code]property[/code] to the given [code]mode[/code]. See [enum RPCMode]. An alternative is annotating methods and properties with the corresponding keywords ([code]remote[/code], [code]sync[/code], [code]master[/code], [code]slave[/code]). By default, properties are not exposed to networking (and RPCs). Also see [method rpc] and [method rpc_config] for methods. </description> </method> <method name="rset_id"> @@ -603,7 +618,7 @@ <argument index="2" name="value" type="Variant"> </argument> <description> - Remotely changes property's value on a specific peer identified by [i]peer_id[/i]. + Remotely changes the property's value on a specific peer identified by [code]peer_id[/code]. </description> </method> <method name="rset_unreliable"> @@ -614,7 +629,7 @@ <argument index="1" name="value" type="Variant"> </argument> <description> - Remotely changes property's value on other peers (and locally) using an unreliable protocol. + Remotely changes the property's value on other peers (and locally) using an unreliable protocol. </description> </method> <method name="rset_unreliable_id"> @@ -627,7 +642,7 @@ <argument index="2" name="value" type="Variant"> </argument> <description> - Remotely changes property's value on a specific peer identified by [i]peer_id[/i] using an unreliable protocol. + Remotely changes property's value on a specific peer identified by [code]peer_id[/code] using an unreliable protocol. </description> </method> <method name="set_display_folded"> @@ -647,7 +662,7 @@ <argument index="1" name="recursive" type="bool" default="true"> </argument> <description> - Sets the node network master to the peer with the given peer ID. The network master is the peer that has authority over it on the network. Inherited from the parent node by default, which ultimately defaults to peer ID 1 (the server). + Sets the node's network master to the peer with the given peer ID. The network master is the peer that has authority over the node on the network. Useful in conjunction with the [code]master[/code] and [code]slave[/code] keywords. Inherited from the parent node by default, which ultimately defaults to peer ID 1 (the server). If [code]recursive[/code], the given peer is recursively set as the master for all children of this node. </description> </method> <method name="set_physics_process"> @@ -665,6 +680,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> + Enables or disables internal physics for this node. Internal physics processing happens in isolation from the normal [method]_physics_process[/code] calls and is used by some nodes internally to guarantee proper functioning even if the node is paused or physics processing is disabled for scripting ([method set_physics_process]). Only useful for advanced uses to manipulate built-in nodes behaviour. </description> </method> <method name="set_process"> @@ -691,6 +707,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> + Enables or disabled internal processing for this node. Internal processing happens in isolation from the normal [method]_process[/code] calls and is used by some nodes internally to guarantee proper functioning even if the node is paused or processing is disabled for scripting ([method set_process]). Only useful for advanced uses to manipulate built-in nodes behaviour. </description> </method> <method name="set_process_unhandled_input"> @@ -717,6 +734,7 @@ <argument index="0" name="load_placeholder" type="bool"> </argument> <description> + Sets whether this is an instance load placeholder. See [InstancePlaceholder]. </description> </method> </methods> @@ -725,13 +743,13 @@ When a scene is instanced from a file, its topmost node contains the filename from which it was loaded. </member> <member name="name" type="String" setter="set_name" getter="get_name"> - The name of the node. This name is unique among the siblings (other child nodes from the same parent). - When set to an existing name, the node will be automatically renamed + The name of the node. This name is unique among the siblings (other child nodes from the same parent). When set to an existing name, the node will be automatically renamed </member> <member name="owner" type="Node" setter="set_owner" getter="get_owner"> - The node owner. A node can have any other node as owner (as long as it is a valid parent, grandparent, etc. ascending in the tree). When saving a node (using SceneSaver) all the nodes it owns will be saved with it. This allows for the creation of complex [SceneTree]s, with instancing and subinstancing. + The node owner. A node can have any other node as owner (as long as it is a valid parent, grandparent, etc. ascending in the tree). When saving a node (using [PackedScene]) all the nodes it owns will be saved with it. This allows for the creation of complex [SceneTree]s, with instancing and subinstancing. </member> <member name="pause_mode" type="int" setter="set_pause_mode" getter="get_pause_mode" enum="Node.PauseMode"> + Pause mode. How the node will behave if the [SceneTree] is paused. </member> </members> <signals> @@ -752,7 +770,7 @@ </signal> <signal name="tree_exiting"> <description> - Emitted when the node is still active but about to exit the tree. This is the right place for de-initialization. + Emitted when the node is still active but about to exit the tree. This is the right place for de-initialization (or a "destructor", if you will). </description> </signal> </signals> @@ -800,33 +818,37 @@ Notification received when the node's [NodePath] changed. </constant> <constant name="NOTIFICATION_TRANSLATION_CHANGED" value="24"> + Notification received when translations may have changed. Can be triggered by the user changing the locale. Can be used to respond to language changes, for example to change the UI strings on the fly. Useful when working with the built-in translation support, like [method Object.tr]. </constant> <constant name="NOTIFICATION_INTERNAL_PROCESS" value="25"> + Notification received every frame when the internal process flag is set (see [method set_process_internal]). </constant> <constant name="NOTIFICATION_INTERNAL_PHYSICS_PROCESS" value="26"> + Notification received every frame when the internal physics process flag is set (see [method set_physics_process_internal]). </constant> <constant name="RPC_MODE_DISABLED" value="0" enum="RPCMode"> + Used with [method rpc_config] or [method rset_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods. </constant> <constant name="RPC_MODE_REMOTE" value="1" enum="RPCMode"> - Call a method remotely. + Used with [method rpc_config] or [method rset_config] to set a method to be called or a property to be changed only on the remote end, not locally. Analogous to the [code]remote[/code] keyword. </constant> <constant name="RPC_MODE_SYNC" value="2" enum="RPCMode"> - Call a method both remotely and locally. + Used with [method rpc_config] or [method rset_config] to set a method to be called or a property to be changed both on the remote end and locally. Analogous to the [code]sync[/code] keyword. </constant> <constant name="RPC_MODE_MASTER" value="3" enum="RPCMode"> - Call a method if the Node is Master. + Used with [method rpc_config] or [method rset_config] to set a method to be called or a property to be changed only on the network master for this node. Analogous to the [code]master[/code] keyword. See [method set_network_master]. </constant> <constant name="RPC_MODE_SLAVE" value="4" enum="RPCMode"> - Call a method if the Node is Slave. + Used with [method rpc_config] or [method rset_config] to set a method to be called or a property to be changed only on slaves for this node. Analogous to the [code]slave[/code] keyword. See [method set_network_master]. </constant> <constant name="PAUSE_MODE_INHERIT" value="0" enum="PauseMode"> - Inherits pause mode from parent. For root node, it is equivalent to PAUSE_MODE_STOP. + Inherits pause mode from the node's parent. For the root node, it is equivalent to PAUSE_MODE_STOP. Default. </constant> <constant name="PAUSE_MODE_STOP" value="1" enum="PauseMode"> - Stop processing when SceneTree is paused. + Stop processing when the [SceneTree] is paused. </constant> <constant name="PAUSE_MODE_PROCESS" value="2" enum="PauseMode"> - Continue to process regardless of SceneTree pause state. + Continue to process regardless of the [SceneTree] pause state. </constant> <constant name="DUPLICATE_SIGNALS" value="1" enum="DuplicateFlags"> Duplicate the node's signals. diff --git a/doc/classes/Node2D.xml b/doc/classes/Node2D.xml index 0b462967a1..a61678041f 100644 --- a/doc/classes/Node2D.xml +++ b/doc/classes/Node2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Node2D" inherits="CanvasItem" category="Core" version="3.1-dev"> +<class name="Node2D" inherits="CanvasItem" category="Core" version="3.1"> <brief_description> A 2D game object, parent of all 2D related nodes. Has a position, rotation, scale and Z-index. </brief_description> diff --git a/doc/classes/NodePath.xml b/doc/classes/NodePath.xml index 48effa5918..f589fa12b7 100644 --- a/doc/classes/NodePath.xml +++ b/doc/classes/NodePath.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NodePath" category="Built-In Types" version="3.1-dev"> +<class name="NodePath" category="Built-In Types" version="3.1"> <brief_description> Pre-parsed scene tree path. </brief_description> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index f37c80efc9..a98385f1d2 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OS" inherits="Object" category="Core" version="3.1-dev"> +<class name="OS" inherits="Object" category="Core" version="3.1"> <brief_description> Operating System functions. </brief_description> @@ -385,6 +385,10 @@ </return> <description> Returns the absolute directory path where user data is written ([code]user://[/code]). + On Linux, this is [code]~/.local/share/godot/app_userdata/[project_name][/code], or [code]~/.local/share/[custom_name][/code] if [code]use_custom_user_dir[/code] is set. + On macOS, this is [code]~/Library/Application Support/Godot/app_userdata/[project_name][/code], or [code]~/Library/Application Support/[custom_name][/code] if [code]use_custom_user_dir[/code] is set. + On Windows, this is [code]%APPDATA%/Godot/app_userdata/[project_name][/code], or [code]%APPDATA%/[custom_name][/code] if [code]use_custom_user_dir[/code] is set. + If the project name is empty, [code]user://[/code] falls back to [code]res://[/code]. </description> </method> <method name="get_virtual_keyboard_height"> diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index 663eb2be56..b5986ec0f5 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Object" category="Core" version="3.1-dev"> +<class name="Object" category="Core" version="3.1"> <brief_description> Base class for all non built-in types. </brief_description> diff --git a/doc/classes/OccluderPolygon2D.xml b/doc/classes/OccluderPolygon2D.xml index 9824c7868d..e8d6b54f27 100644 --- a/doc/classes/OccluderPolygon2D.xml +++ b/doc/classes/OccluderPolygon2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OccluderPolygon2D" inherits="Resource" category="Core" version="3.1-dev"> +<class name="OccluderPolygon2D" inherits="Resource" category="Core" version="3.1"> <brief_description> Defines a 2D polygon for LightOccluder2D. </brief_description> diff --git a/doc/classes/OmniLight.xml b/doc/classes/OmniLight.xml index 2fdcc86d55..0ed133f52e 100644 --- a/doc/classes/OmniLight.xml +++ b/doc/classes/OmniLight.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OmniLight" inherits="Light" category="Core" version="3.1-dev"> +<class name="OmniLight" inherits="Light" category="Core" version="3.1"> <brief_description> OmniDirectional Light, such as a light bulb or a candle. </brief_description> diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml index cefb02d724..de6f60c384 100644 --- a/doc/classes/OptionButton.xml +++ b/doc/classes/OptionButton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OptionButton" inherits="Button" category="Core" version="3.1-dev"> +<class name="OptionButton" inherits="Button" category="Core" version="3.1"> <brief_description> Button control that provides selectable options when pressed. </brief_description> diff --git a/doc/classes/PCKPacker.xml b/doc/classes/PCKPacker.xml index ed7a343f03..01985a9bb3 100644 --- a/doc/classes/PCKPacker.xml +++ b/doc/classes/PCKPacker.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PCKPacker" inherits="Reference" category="Core" version="3.1-dev"> +<class name="PCKPacker" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/PHashTranslation.xml b/doc/classes/PHashTranslation.xml index 52eb2748da..18c72a0576 100644 --- a/doc/classes/PHashTranslation.xml +++ b/doc/classes/PHashTranslation.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PHashTranslation" inherits="Translation" category="Core" version="3.1-dev"> +<class name="PHashTranslation" inherits="Translation" category="Core" version="3.1"> <brief_description> Optimized translation. </brief_description> diff --git a/doc/classes/PackedDataContainer.xml b/doc/classes/PackedDataContainer.xml index edabaace8f..e6dbe57925 100644 --- a/doc/classes/PackedDataContainer.xml +++ b/doc/classes/PackedDataContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PackedDataContainer" inherits="Resource" category="Core" version="3.1-dev"> +<class name="PackedDataContainer" inherits="Resource" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/PackedDataContainerRef.xml b/doc/classes/PackedDataContainerRef.xml index 2f418991de..371fe5a5ac 100644 --- a/doc/classes/PackedDataContainerRef.xml +++ b/doc/classes/PackedDataContainerRef.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PackedDataContainerRef" inherits="Reference" category="Core" version="3.1-dev"> +<class name="PackedDataContainerRef" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml index b6ef9db068..8d810bc9c4 100644 --- a/doc/classes/PackedScene.xml +++ b/doc/classes/PackedScene.xml @@ -1,11 +1,18 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PackedScene" inherits="Resource" category="Core" version="3.1-dev"> +<class name="PackedScene" inherits="Resource" category="Core" version="3.1"> <brief_description> An abstraction of a serialized scene. </brief_description> <description> A simplified interface to a scene file. Provides access to operations and checks that can be performed on the scene resource itself. - TODO: explain ownership, and that node does not need to own itself + Can be used to save a node to a file. When saving, the node as well as all the node it owns get saved (see [code]owner[/code] property on [Node]). Note that the node doesn't need to own itself. + Example of saving a node: + [codeblock] + var scene = PackedScene.new() + var result = scene.pack(child) + if result == OK: + ResourceSaver.save("res://path/name.scn", scene) // or user://... + [/codeblock] </description> <tutorials> </tutorials> diff --git a/doc/classes/PacketPeer.xml b/doc/classes/PacketPeer.xml index 6fdbaf27e6..a4cf0c8029 100644 --- a/doc/classes/PacketPeer.xml +++ b/doc/classes/PacketPeer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PacketPeer" inherits="Reference" category="Core" version="3.1-dev"> +<class name="PacketPeer" inherits="Reference" category="Core" version="3.1"> <brief_description> Abstraction and base class for packet-based protocols. </brief_description> diff --git a/doc/classes/PacketPeerStream.xml b/doc/classes/PacketPeerStream.xml index 0ad473f644..9e3195bb44 100644 --- a/doc/classes/PacketPeerStream.xml +++ b/doc/classes/PacketPeerStream.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PacketPeerStream" inherits="PacketPeer" category="Core" version="3.1-dev"> +<class name="PacketPeerStream" inherits="PacketPeer" category="Core" version="3.1"> <brief_description> Wrapper to use a PacketPeer over a StreamPeer. </brief_description> diff --git a/doc/classes/PacketPeerUDP.xml b/doc/classes/PacketPeerUDP.xml index 29abcda9d9..1b821e06cf 100644 --- a/doc/classes/PacketPeerUDP.xml +++ b/doc/classes/PacketPeerUDP.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PacketPeerUDP" inherits="PacketPeer" category="Core" version="3.1-dev"> +<class name="PacketPeerUDP" inherits="PacketPeer" category="Core" version="3.1"> <brief_description> UDP packet peer. </brief_description> diff --git a/doc/classes/Panel.xml b/doc/classes/Panel.xml index 3afda37355..758925e969 100644 --- a/doc/classes/Panel.xml +++ b/doc/classes/Panel.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Panel" inherits="Control" category="Core" version="3.1-dev"> +<class name="Panel" inherits="Control" category="Core" version="3.1"> <brief_description> Provides an opaque background for [Control] children. </brief_description> diff --git a/doc/classes/PanelContainer.xml b/doc/classes/PanelContainer.xml index 5b76f49687..f5c351fa21 100644 --- a/doc/classes/PanelContainer.xml +++ b/doc/classes/PanelContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PanelContainer" inherits="Container" category="Core" version="3.1-dev"> +<class name="PanelContainer" inherits="Container" category="Core" version="3.1"> <brief_description> Panel container type. </brief_description> diff --git a/doc/classes/PanoramaSky.xml b/doc/classes/PanoramaSky.xml index 0196f7a73e..eb288d13be 100644 --- a/doc/classes/PanoramaSky.xml +++ b/doc/classes/PanoramaSky.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PanoramaSky" inherits="Sky" category="Core" version="3.1-dev"> +<class name="PanoramaSky" inherits="Sky" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/ParallaxBackground.xml b/doc/classes/ParallaxBackground.xml index c8b15b3c7d..2409b7a1c1 100644 --- a/doc/classes/ParallaxBackground.xml +++ b/doc/classes/ParallaxBackground.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ParallaxBackground" inherits="CanvasLayer" category="Core" version="3.1-dev"> +<class name="ParallaxBackground" inherits="CanvasLayer" category="Core" version="3.1"> <brief_description> A node used to create a parallax scrolling background. </brief_description> diff --git a/doc/classes/ParallaxLayer.xml b/doc/classes/ParallaxLayer.xml index b5d4e10d7e..662a15e043 100644 --- a/doc/classes/ParallaxLayer.xml +++ b/doc/classes/ParallaxLayer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ParallaxLayer" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="ParallaxLayer" inherits="Node2D" category="Core" version="3.1"> <brief_description> A parallax scrolling layer to be used with [ParallaxBackground]. </brief_description> diff --git a/doc/classes/Particles.xml b/doc/classes/Particles.xml index b56c15f246..04177aca25 100644 --- a/doc/classes/Particles.xml +++ b/doc/classes/Particles.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Particles" inherits="GeometryInstance" category="Core" version="3.1-dev"> +<class name="Particles" inherits="GeometryInstance" category="Core" version="3.1"> <brief_description> 3D particle emitter. </brief_description> diff --git a/doc/classes/Particles2D.xml b/doc/classes/Particles2D.xml index 88a373b7a9..47265054b0 100644 --- a/doc/classes/Particles2D.xml +++ b/doc/classes/Particles2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Particles2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="Particles2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> 2D particle emitter. </brief_description> diff --git a/doc/classes/ParticlesMaterial.xml b/doc/classes/ParticlesMaterial.xml index a6c463d307..354b98485e 100644 --- a/doc/classes/ParticlesMaterial.xml +++ b/doc/classes/ParticlesMaterial.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ParticlesMaterial" inherits="Material" category="Core" version="3.1-dev"> +<class name="ParticlesMaterial" inherits="Material" category="Core" version="3.1"> <brief_description> Particle properties for [Particles] and [Particles2D] nodes. </brief_description> @@ -132,7 +132,7 @@ Orbital velocity randomness ratio. Default value: [code]0[/code]. </member> <member name="radial_accel" type="float" setter="set_param" getter="get_param"> - Linear acceleration applied to each particle. + Radial acceleration applied to each particle. </member> <member name="radial_accel_curve" type="Texture" setter="set_param_texture" getter="get_param_texture"> Each particle's radial acceleration will vary along this [CurveTexture]. diff --git a/doc/classes/Path.xml b/doc/classes/Path.xml index 48d41c89c1..621a513da3 100644 --- a/doc/classes/Path.xml +++ b/doc/classes/Path.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Path" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="Path" inherits="Spatial" category="Core" version="3.1"> <brief_description> Container for a [Curve3D]. </brief_description> diff --git a/doc/classes/Path2D.xml b/doc/classes/Path2D.xml index dcef22c241..5e40fb6956 100644 --- a/doc/classes/Path2D.xml +++ b/doc/classes/Path2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Path2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="Path2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Contains a [Curve2D] path for [PathFollow2D] nodes to follow. </brief_description> diff --git a/doc/classes/PathFollow.xml b/doc/classes/PathFollow.xml index c248e6f868..650fed7ec6 100644 --- a/doc/classes/PathFollow.xml +++ b/doc/classes/PathFollow.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PathFollow" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="PathFollow" inherits="Spatial" category="Core" version="3.1"> <brief_description> Point sampler for a [Path]. </brief_description> diff --git a/doc/classes/PathFollow2D.xml b/doc/classes/PathFollow2D.xml index 995c65d4fa..f9940dab2f 100644 --- a/doc/classes/PathFollow2D.xml +++ b/doc/classes/PathFollow2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PathFollow2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="PathFollow2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Point sampler for a [Path2D]. </brief_description> diff --git a/doc/classes/Performance.xml b/doc/classes/Performance.xml index c67b9e2f07..de3a251a79 100644 --- a/doc/classes/Performance.xml +++ b/doc/classes/Performance.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Performance" inherits="Object" category="Core" version="3.1-dev"> +<class name="Performance" inherits="Object" category="Core" version="3.1"> <brief_description> Exposes performance related data. </brief_description> diff --git a/doc/classes/Physics2DDirectBodyState.xml b/doc/classes/Physics2DDirectBodyState.xml index d1634974f4..73a2d792ab 100644 --- a/doc/classes/Physics2DDirectBodyState.xml +++ b/doc/classes/Physics2DDirectBodyState.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Physics2DDirectBodyState" inherits="Object" category="Core" version="3.1-dev"> +<class name="Physics2DDirectBodyState" inherits="Object" category="Core" version="3.1"> <brief_description> Direct access object to a physics body in the [Physics2DServer]. </brief_description> diff --git a/doc/classes/Physics2DDirectBodyStateSW.xml b/doc/classes/Physics2DDirectBodyStateSW.xml index 7d04e483ff..cb1e9239b3 100644 --- a/doc/classes/Physics2DDirectBodyStateSW.xml +++ b/doc/classes/Physics2DDirectBodyStateSW.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Physics2DDirectBodyStateSW" inherits="Physics2DDirectBodyState" category="Core" version="3.1-dev"> +<class name="Physics2DDirectBodyStateSW" inherits="Physics2DDirectBodyState" category="Core" version="3.1"> <brief_description> Software implementation of [Physics2DDirectBodyState]. </brief_description> diff --git a/doc/classes/Physics2DDirectSpaceState.xml b/doc/classes/Physics2DDirectSpaceState.xml index b3a33e9216..b55702dac4 100644 --- a/doc/classes/Physics2DDirectSpaceState.xml +++ b/doc/classes/Physics2DDirectSpaceState.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Physics2DDirectSpaceState" inherits="Object" category="Core" version="3.1-dev"> +<class name="Physics2DDirectSpaceState" inherits="Object" category="Core" version="3.1"> <brief_description> Direct access object to a space in the [Physics2DServer]. </brief_description> diff --git a/doc/classes/Physics2DServer.xml b/doc/classes/Physics2DServer.xml index 644731516f..98535dd330 100644 --- a/doc/classes/Physics2DServer.xml +++ b/doc/classes/Physics2DServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Physics2DServer" inherits="Object" category="Core" version="3.1-dev"> +<class name="Physics2DServer" inherits="Object" category="Core" version="3.1"> <brief_description> Physics 2D Server. </brief_description> @@ -713,9 +713,11 @@ </argument> <argument index="2" name="motion" type="Vector2"> </argument> - <argument index="3" name="margin" type="float" default="0.08"> + <argument index="3" name="infinite_inertia" type="bool"> </argument> - <argument index="4" name="result" type="Physics2DTestMotionResult" default="null"> + <argument index="4" name="margin" type="float" default="0.08"> + </argument> + <argument index="5" name="result" type="Physics2DTestMotionResult" default="null"> </argument> <description> Returns whether a body can move from a given point in a given direction. Apart from the boolean return value, a [Physics2DTestMotionResult] can be passed to return additional information in. diff --git a/doc/classes/Physics2DServerSW.xml b/doc/classes/Physics2DServerSW.xml index 25ca5dd4d2..49157bd94b 100644 --- a/doc/classes/Physics2DServerSW.xml +++ b/doc/classes/Physics2DServerSW.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Physics2DServerSW" inherits="Physics2DServer" category="Core" version="3.1-dev"> +<class name="Physics2DServerSW" inherits="Physics2DServer" category="Core" version="3.1"> <brief_description> Software implementation of [Physics2DServer]. </brief_description> diff --git a/doc/classes/Physics2DShapeQueryParameters.xml b/doc/classes/Physics2DShapeQueryParameters.xml index 209623c62a..391ad6276f 100644 --- a/doc/classes/Physics2DShapeQueryParameters.xml +++ b/doc/classes/Physics2DShapeQueryParameters.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Physics2DShapeQueryParameters" inherits="Reference" category="Core" version="3.1-dev"> +<class name="Physics2DShapeQueryParameters" inherits="Reference" category="Core" version="3.1"> <brief_description> Parameters to be sent to a 2D shape physics query. </brief_description> diff --git a/doc/classes/Physics2DShapeQueryResult.xml b/doc/classes/Physics2DShapeQueryResult.xml index 2e2180ee0f..52e7294e24 100644 --- a/doc/classes/Physics2DShapeQueryResult.xml +++ b/doc/classes/Physics2DShapeQueryResult.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Physics2DShapeQueryResult" inherits="Reference" category="Core" version="3.1-dev"> +<class name="Physics2DShapeQueryResult" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Physics2DTestMotionResult.xml b/doc/classes/Physics2DTestMotionResult.xml index 943ef72ffb..3b864433f0 100644 --- a/doc/classes/Physics2DTestMotionResult.xml +++ b/doc/classes/Physics2DTestMotionResult.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Physics2DTestMotionResult" inherits="Reference" category="Core" version="3.1-dev"> +<class name="Physics2DTestMotionResult" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/PhysicsBody.xml b/doc/classes/PhysicsBody.xml index b765bb1f1f..e252aaa048 100644 --- a/doc/classes/PhysicsBody.xml +++ b/doc/classes/PhysicsBody.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsBody" inherits="CollisionObject" category="Core" version="3.1-dev"> +<class name="PhysicsBody" inherits="CollisionObject" category="Core" version="3.1"> <brief_description> Base class for all objects affected by physics in 3D space. </brief_description> diff --git a/doc/classes/PhysicsBody2D.xml b/doc/classes/PhysicsBody2D.xml index 80d72512fe..42b1eac5e4 100644 --- a/doc/classes/PhysicsBody2D.xml +++ b/doc/classes/PhysicsBody2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsBody2D" inherits="CollisionObject2D" category="Core" version="3.1-dev"> +<class name="PhysicsBody2D" inherits="CollisionObject2D" category="Core" version="3.1"> <brief_description> Base class for all objects affected by physics in 2D space. </brief_description> diff --git a/doc/classes/PhysicsDirectBodyState.xml b/doc/classes/PhysicsDirectBodyState.xml index fa0e529a73..74190d0780 100644 --- a/doc/classes/PhysicsDirectBodyState.xml +++ b/doc/classes/PhysicsDirectBodyState.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsDirectBodyState" inherits="Object" category="Core" version="3.1-dev"> +<class name="PhysicsDirectBodyState" inherits="Object" category="Core" version="3.1"> <brief_description> </brief_description> <description> @@ -9,6 +9,14 @@ <demos> </demos> <methods> + <method name="add_central_force"> + <return type="void"> + </return> + <argument index="0" name="force" type="Vector3"> + </argument> + <description> + </description> + </method> <method name="add_force"> <return type="void"> </return> @@ -19,6 +27,14 @@ <description> </description> </method> + <method name="add_torque"> + <return type="void"> + </return> + <argument index="0" name="torque" type="Vector3"> + </argument> + <description> + </description> + </method> <method name="apply_impulse"> <return type="void"> </return> @@ -29,7 +45,7 @@ <description> </description> </method> - <method name="apply_torqe_impulse"> + <method name="apply_torque_impulse"> <return type="void"> </return> <argument index="0" name="j" type="Vector3"> diff --git a/doc/classes/PhysicsDirectSpaceState.xml b/doc/classes/PhysicsDirectSpaceState.xml index e33718edf0..fabf153dac 100644 --- a/doc/classes/PhysicsDirectSpaceState.xml +++ b/doc/classes/PhysicsDirectSpaceState.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsDirectSpaceState" inherits="Object" category="Core" version="3.1-dev"> +<class name="PhysicsDirectSpaceState" inherits="Object" category="Core" version="3.1"> <brief_description> Direct access object to a space in the [PhysicsServer]. </brief_description> diff --git a/doc/classes/PhysicsServer.xml b/doc/classes/PhysicsServer.xml index 02172a310d..6c3a435360 100644 --- a/doc/classes/PhysicsServer.xml +++ b/doc/classes/PhysicsServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsServer" inherits="Object" category="Core" version="3.1-dev"> +<class name="PhysicsServer" inherits="Object" category="Core" version="3.1"> <brief_description> Server interface for low level physics access. </brief_description> diff --git a/doc/classes/PhysicsShapeQueryParameters.xml b/doc/classes/PhysicsShapeQueryParameters.xml index 6bd37dda32..2f36e81e27 100644 --- a/doc/classes/PhysicsShapeQueryParameters.xml +++ b/doc/classes/PhysicsShapeQueryParameters.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsShapeQueryParameters" inherits="Reference" category="Core" version="3.1-dev"> +<class name="PhysicsShapeQueryParameters" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/PhysicsShapeQueryResult.xml b/doc/classes/PhysicsShapeQueryResult.xml index bb78071e85..080d7389b7 100644 --- a/doc/classes/PhysicsShapeQueryResult.xml +++ b/doc/classes/PhysicsShapeQueryResult.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsShapeQueryResult" inherits="Reference" category="Core" version="3.1-dev"> +<class name="PhysicsShapeQueryResult" inherits="Reference" category="Core" version="3.1"> <brief_description> Result of a shape query in Physics2DServer. </brief_description> diff --git a/doc/classes/PinJoint.xml b/doc/classes/PinJoint.xml index 7c94347008..470c22cd4c 100644 --- a/doc/classes/PinJoint.xml +++ b/doc/classes/PinJoint.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PinJoint" inherits="Joint" category="Core" version="3.1-dev"> +<class name="PinJoint" inherits="Joint" category="Core" version="3.1"> <brief_description> Pin Joint for 3D Shapes. </brief_description> diff --git a/doc/classes/PinJoint2D.xml b/doc/classes/PinJoint2D.xml index 0982ffacae..42708151ec 100644 --- a/doc/classes/PinJoint2D.xml +++ b/doc/classes/PinJoint2D.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PinJoint2D" inherits="Joint2D" category="Core" version="3.1-dev"> +<class name="PinJoint2D" inherits="Joint2D" category="Core" version="3.1"> <brief_description> Pin Joint for 2D Shapes. </brief_description> <description> - Pin Joint for 2D Rigid Bodies. It pins 2 bodies (rigid or static) together, or a single body to a fixed position in space. + Pin Joint for 2D Rigid Bodies. It pins two bodies (rigid or static) together. </description> <tutorials> </tutorials> diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml index f478b2d384..157bf42239 100644 --- a/doc/classes/Plane.xml +++ b/doc/classes/Plane.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Plane" category="Built-In Types" version="3.1-dev"> +<class name="Plane" category="Built-In Types" version="3.1"> <brief_description> Plane in hessian form. </brief_description> diff --git a/doc/classes/PlaneMesh.xml b/doc/classes/PlaneMesh.xml index 60bc1f6613..fc293ab4df 100644 --- a/doc/classes/PlaneMesh.xml +++ b/doc/classes/PlaneMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PlaneMesh" inherits="PrimitiveMesh" category="Core" version="3.1-dev"> +<class name="PlaneMesh" inherits="PrimitiveMesh" category="Core" version="3.1"> <brief_description> Class representing a planar [PrimitiveMesh]. </brief_description> diff --git a/doc/classes/PlaneShape.xml b/doc/classes/PlaneShape.xml index e0c1fdf25b..bc3faf7c01 100644 --- a/doc/classes/PlaneShape.xml +++ b/doc/classes/PlaneShape.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PlaneShape" inherits="Shape" category="Core" version="3.1-dev"> +<class name="PlaneShape" inherits="Shape" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Polygon2D.xml b/doc/classes/Polygon2D.xml index a538cd2f05..429114a128 100644 --- a/doc/classes/Polygon2D.xml +++ b/doc/classes/Polygon2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Polygon2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="Polygon2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> A 2D polygon. </brief_description> @@ -31,6 +31,8 @@ <member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon"> The polygon's list of vertices. The final point will be connected to the first. </member> + <member name="splits" type="PoolIntArray" setter="set_splits" getter="get_splits"> + </member> <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> The polygon's fill texture. Use [code]uv[/code] to set texture coordinates. </member> diff --git a/doc/classes/PolygonPathFinder.xml b/doc/classes/PolygonPathFinder.xml index 3c57b4ca18..e4a4d9b976 100644 --- a/doc/classes/PolygonPathFinder.xml +++ b/doc/classes/PolygonPathFinder.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PolygonPathFinder" inherits="Resource" category="Core" version="3.1-dev"> +<class name="PolygonPathFinder" inherits="Resource" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/PoolByteArray.xml b/doc/classes/PoolByteArray.xml index 7982c91ea9..0118e7477a 100644 --- a/doc/classes/PoolByteArray.xml +++ b/doc/classes/PoolByteArray.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PoolByteArray" category="Built-In Types" version="3.1-dev"> +<class name="PoolByteArray" category="Built-In Types" version="3.1"> <brief_description> Raw byte array. </brief_description> diff --git a/doc/classes/PoolColorArray.xml b/doc/classes/PoolColorArray.xml index c61f39b238..0a4221728e 100644 --- a/doc/classes/PoolColorArray.xml +++ b/doc/classes/PoolColorArray.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PoolColorArray" category="Built-In Types" version="3.1-dev"> +<class name="PoolColorArray" category="Built-In Types" version="3.1"> <brief_description> Array of Colors </brief_description> diff --git a/doc/classes/PoolIntArray.xml b/doc/classes/PoolIntArray.xml index 7b9bb96730..7709a69c84 100644 --- a/doc/classes/PoolIntArray.xml +++ b/doc/classes/PoolIntArray.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PoolIntArray" category="Built-In Types" version="3.1-dev"> +<class name="PoolIntArray" category="Built-In Types" version="3.1"> <brief_description> Integer Array. </brief_description> diff --git a/doc/classes/PoolRealArray.xml b/doc/classes/PoolRealArray.xml index b0f971ae3e..19f31f7dfb 100644 --- a/doc/classes/PoolRealArray.xml +++ b/doc/classes/PoolRealArray.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PoolRealArray" category="Built-In Types" version="3.1-dev"> +<class name="PoolRealArray" category="Built-In Types" version="3.1"> <brief_description> Real Array. </brief_description> diff --git a/doc/classes/PoolStringArray.xml b/doc/classes/PoolStringArray.xml index 9db0af34be..3d971d1ac9 100644 --- a/doc/classes/PoolStringArray.xml +++ b/doc/classes/PoolStringArray.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PoolStringArray" category="Built-In Types" version="3.1-dev"> +<class name="PoolStringArray" category="Built-In Types" version="3.1"> <brief_description> String Array. </brief_description> diff --git a/doc/classes/PoolVector2Array.xml b/doc/classes/PoolVector2Array.xml index 5c8599f220..14c226d019 100644 --- a/doc/classes/PoolVector2Array.xml +++ b/doc/classes/PoolVector2Array.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PoolVector2Array" category="Built-In Types" version="3.1-dev"> +<class name="PoolVector2Array" category="Built-In Types" version="3.1"> <brief_description> An Array of Vector2. </brief_description> diff --git a/doc/classes/PoolVector3Array.xml b/doc/classes/PoolVector3Array.xml index 944bb767e0..27ddfa10a5 100644 --- a/doc/classes/PoolVector3Array.xml +++ b/doc/classes/PoolVector3Array.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PoolVector3Array" category="Built-In Types" version="3.1-dev"> +<class name="PoolVector3Array" category="Built-In Types" version="3.1"> <brief_description> An Array of Vector3. </brief_description> diff --git a/doc/classes/Popup.xml b/doc/classes/Popup.xml index b6ee43254e..abf6ec3238 100644 --- a/doc/classes/Popup.xml +++ b/doc/classes/Popup.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Popup" inherits="Control" category="Core" version="3.1-dev"> +<class name="Popup" inherits="Control" category="Core" version="3.1"> <brief_description> Base container control for popups and dialogs. </brief_description> diff --git a/doc/classes/PopupDialog.xml b/doc/classes/PopupDialog.xml index eac361f404..4f15fb4b05 100644 --- a/doc/classes/PopupDialog.xml +++ b/doc/classes/PopupDialog.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PopupDialog" inherits="Popup" category="Core" version="3.1-dev"> +<class name="PopupDialog" inherits="Popup" category="Core" version="3.1"> <brief_description> Base class for Popup Dialogs. </brief_description> diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index 62911c1cf7..6ead220236 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PopupMenu" inherits="Popup" category="Core" version="3.1-dev"> +<class name="PopupMenu" inherits="Popup" category="Core" version="3.1"> <brief_description> PopupMenu displays a list of options. </brief_description> @@ -24,6 +24,19 @@ Add a new checkable item with text "label". An id can optionally be provided, as well as an accelerator. If no id is provided, one will be created from the index. Note that checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. </description> </method> + <method name="add_radio_check_item"> + <return type="void"> + </return> + <argument index="0" name="label" type="String"> + </argument> + <argument index="1" name="id" type="int" default="-1"> + </argument> + <argument index="2" name="accel" type="int" default="0"> + </argument> + <description> + The same as [method add_check_item] but the inserted item will look as a radio button. Remember this is just cosmetic and you have to add the logic for checking/unchecking items in radio groups. + </description> + </method> <method name="add_check_shortcut"> <return type="void"> </return> @@ -36,6 +49,18 @@ <description> </description> </method> + <method name="add_radio_check_shortcut"> + <return type="void"> + </return> + <argument index="0" name="shortcut" type="ShortCut"> + </argument> + <argument index="1" name="id" type="int" default="-1"> + </argument> + <argument index="2" name="global" type="bool" default="false"> + </argument> + <description> + </description> + </method> <method name="add_icon_check_item"> <return type="void"> </return> @@ -239,7 +264,16 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Return whether the item at index "idx" has a checkbox. Note that checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. + Return whether the item at index "idx" is checkable in some way, i.e., whether has a checkbox or radio button. Note that checkable items just display a checkmark or radio button, but don't have any built-in checking behavior and must be checked/unchecked manually. + </description> + </method> + <method name="is_item_radio_checkable" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <description> + Return whether the item at index "idx" has radio-button-style checkability. Remember this is just cosmetic and you have to add the logic for checking/unchecking items in radio groups. </description> </method> <method name="is_item_checked" qualifiers="const"> @@ -248,7 +282,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Return the checkstate status of the item at index "idx". + Return whether the item at index "idx" is checked. </description> </method> <method name="is_item_disabled" qualifiers="const"> @@ -300,6 +334,18 @@ Set whether the item at index "idx" has a checkbox. Note that checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. </description> </method> + <method name="set_item_as_radio_checkable"> + <return type="void"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + The same as [method set_item_as_checkable] but placing a radio button in case of enabling. If used for disabling, it's the same. + Remember this is just cosmetic and you have to add the logic for checking/unchecking items in radio groups. + </description> + </method> <method name="set_item_as_separator"> <return type="void"> </return> diff --git a/doc/classes/PopupPanel.xml b/doc/classes/PopupPanel.xml index 5e8e24d36f..694c29efda 100644 --- a/doc/classes/PopupPanel.xml +++ b/doc/classes/PopupPanel.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PopupPanel" inherits="Popup" category="Core" version="3.1-dev"> +<class name="PopupPanel" inherits="Popup" category="Core" version="3.1"> <brief_description> Class for displaying popups with a panel background. </brief_description> diff --git a/doc/classes/Position2D.xml b/doc/classes/Position2D.xml index 3e29000c5b..6c26bf412c 100644 --- a/doc/classes/Position2D.xml +++ b/doc/classes/Position2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Position2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="Position2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Generic 2D Position hint for editing. </brief_description> diff --git a/doc/classes/Position3D.xml b/doc/classes/Position3D.xml index 2719cdb7f3..7c0875cc0c 100644 --- a/doc/classes/Position3D.xml +++ b/doc/classes/Position3D.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Position3D" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="Position3D" inherits="Spatial" category="Core" version="3.1"> <brief_description> - Generic 3D Position hint for editing + Generic 3D Position hint for editing. </brief_description> <description> Generic 3D Position hint for editing. It's just like a plain [Spatial] but displays as a cross in the 3D-Editor at all times. diff --git a/doc/classes/PrimitiveMesh.xml b/doc/classes/PrimitiveMesh.xml index 8fd8e5da1e..c5bc3d6e47 100644 --- a/doc/classes/PrimitiveMesh.xml +++ b/doc/classes/PrimitiveMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PrimitiveMesh" inherits="Mesh" category="Core" version="3.1-dev"> +<class name="PrimitiveMesh" inherits="Mesh" category="Core" version="3.1"> <brief_description> Base class for all primitive meshes. Handles applying a [Material] to a primitive mesh. </brief_description> diff --git a/doc/classes/PrismMesh.xml b/doc/classes/PrismMesh.xml index 58f7a0dd09..268395c37a 100644 --- a/doc/classes/PrismMesh.xml +++ b/doc/classes/PrismMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PrismMesh" inherits="PrimitiveMesh" category="Core" version="3.1-dev"> +<class name="PrismMesh" inherits="PrimitiveMesh" category="Core" version="3.1"> <brief_description> Class representing a prism-shaped [PrimitiveMesh]. </brief_description> diff --git a/doc/classes/ProceduralSky.xml b/doc/classes/ProceduralSky.xml index 75831465ed..11af73f953 100644 --- a/doc/classes/ProceduralSky.xml +++ b/doc/classes/ProceduralSky.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ProceduralSky" inherits="Sky" category="Core" version="3.1-dev"> +<class name="ProceduralSky" inherits="Sky" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/ProgressBar.xml b/doc/classes/ProgressBar.xml index 44eb82f2a4..919ecd7c86 100644 --- a/doc/classes/ProgressBar.xml +++ b/doc/classes/ProgressBar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ProgressBar" inherits="Range" category="Core" version="3.1-dev"> +<class name="ProgressBar" inherits="Range" category="Core" version="3.1"> <brief_description> General purpose progress bar. </brief_description> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 83dea5d097..44bba8bd20 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ProjectSettings" inherits="Object" category="Core" version="3.1-dev"> +<class name="ProjectSettings" inherits="Object" category="Core" version="3.1"> <brief_description> Contains global variables accessible from everywhere. </brief_description> diff --git a/doc/classes/ProximityGroup.xml b/doc/classes/ProximityGroup.xml index 697bb8ff7e..1f1c45fbf9 100644 --- a/doc/classes/ProximityGroup.xml +++ b/doc/classes/ProximityGroup.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ProximityGroup" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="ProximityGroup" inherits="Spatial" category="Core" version="3.1"> <brief_description> General purpose proximity-detection node. </brief_description> diff --git a/doc/classes/ProxyTexture.xml b/doc/classes/ProxyTexture.xml index 2f50229643..69702ee22e 100644 --- a/doc/classes/ProxyTexture.xml +++ b/doc/classes/ProxyTexture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ProxyTexture" inherits="Texture" category="Core" version="3.1-dev"> +<class name="ProxyTexture" inherits="Texture" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/QuadMesh.xml b/doc/classes/QuadMesh.xml index a295ffc929..a45b2ddf4b 100644 --- a/doc/classes/QuadMesh.xml +++ b/doc/classes/QuadMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="QuadMesh" inherits="PrimitiveMesh" category="Core" version="3.1-dev"> +<class name="QuadMesh" inherits="PrimitiveMesh" category="Core" version="3.1"> <brief_description> Class representing a square mesh. </brief_description> diff --git a/doc/classes/Quat.xml b/doc/classes/Quat.xml index 90301db01f..3a258011b2 100644 --- a/doc/classes/Quat.xml +++ b/doc/classes/Quat.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Quat" category="Built-In Types" version="3.1-dev"> +<class name="Quat" category="Built-In Types" version="3.1"> <brief_description> Quaternion. </brief_description> diff --git a/doc/classes/RID.xml b/doc/classes/RID.xml index 85702727ce..ee34560afd 100644 --- a/doc/classes/RID.xml +++ b/doc/classes/RID.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RID" category="Built-In Types" version="3.1-dev"> +<class name="RID" category="Built-In Types" version="3.1"> <brief_description> Handle for a [Resource]'s unique ID. </brief_description> diff --git a/doc/classes/Range.xml b/doc/classes/Range.xml index 7828445dc4..545f5cc83b 100644 --- a/doc/classes/Range.xml +++ b/doc/classes/Range.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Range" inherits="Control" category="Core" version="3.1-dev"> +<class name="Range" inherits="Control" category="Core" version="3.1"> <brief_description> Abstract base class for range-based controls. </brief_description> diff --git a/doc/classes/RayCast.xml b/doc/classes/RayCast.xml index 76574b305f..dce73d9c29 100644 --- a/doc/classes/RayCast.xml +++ b/doc/classes/RayCast.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RayCast" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="RayCast" inherits="Spatial" category="Core" version="3.1"> <brief_description> Query the closest object intersecting a ray. </brief_description> diff --git a/doc/classes/RayCast2D.xml b/doc/classes/RayCast2D.xml index 7a6ec8ded8..79e733bcdc 100644 --- a/doc/classes/RayCast2D.xml +++ b/doc/classes/RayCast2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RayCast2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="RayCast2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Query the closest object intersecting a ray. </brief_description> diff --git a/doc/classes/RayShape.xml b/doc/classes/RayShape.xml index 5d488cb3f5..e03541011d 100644 --- a/doc/classes/RayShape.xml +++ b/doc/classes/RayShape.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RayShape" inherits="Shape" category="Core" version="3.1-dev"> +<class name="RayShape" inherits="Shape" category="Core" version="3.1"> <brief_description> Ray shape for 3D collisions. </brief_description> @@ -16,6 +16,9 @@ <member name="length" type="float" setter="set_length" getter="get_length"> The ray's length. </member> + <member name="slips_on_slope" type="bool" setter="set_slips_on_slope" getter="get_slips_on_slope"> + If [code]true[/code] allow the shape to return the correct normal. Default value: [code]false[/code]. + </member> </members> <constants> </constants> diff --git a/doc/classes/RayShape2D.xml b/doc/classes/RayShape2D.xml index 3137bbd1ad..37cfe4f2d3 100644 --- a/doc/classes/RayShape2D.xml +++ b/doc/classes/RayShape2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RayShape2D" inherits="Shape2D" category="Core" version="3.1-dev"> +<class name="RayShape2D" inherits="Shape2D" category="Core" version="3.1"> <brief_description> Ray shape for 2D collisions. </brief_description> @@ -16,6 +16,9 @@ <member name="length" type="float" setter="set_length" getter="get_length"> The ray's length. </member> + <member name="slips_on_slope" type="bool" setter="set_slips_on_slope" getter="get_slips_on_slope"> + If [code]true[/code] allow the shape to return the correct normal. Default value: [code]false[/code]. + </member> </members> <constants> </constants> diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml index bafa5a3632..1961aee8b5 100644 --- a/doc/classes/Rect2.xml +++ b/doc/classes/Rect2.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Rect2" category="Built-In Types" version="3.1-dev"> +<class name="Rect2" category="Built-In Types" version="3.1"> <brief_description> 2D Axis-aligned bounding box. </brief_description> diff --git a/doc/classes/RectangleShape2D.xml b/doc/classes/RectangleShape2D.xml index 5e2bdf040a..4a312503f4 100644 --- a/doc/classes/RectangleShape2D.xml +++ b/doc/classes/RectangleShape2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RectangleShape2D" inherits="Shape2D" category="Core" version="3.1-dev"> +<class name="RectangleShape2D" inherits="Shape2D" category="Core" version="3.1"> <brief_description> Rectangle shape for 2D collisions. </brief_description> diff --git a/doc/classes/Reference.xml b/doc/classes/Reference.xml index 3f4f499b3e..3238501633 100644 --- a/doc/classes/Reference.xml +++ b/doc/classes/Reference.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Reference" inherits="Object" category="Core" version="3.1-dev"> +<class name="Reference" inherits="Object" category="Core" version="3.1"> <brief_description> Base class for anything that keeps a reference count. </brief_description> diff --git a/doc/classes/ReferenceRect.xml b/doc/classes/ReferenceRect.xml index 1946ee8b81..4453e8726f 100644 --- a/doc/classes/ReferenceRect.xml +++ b/doc/classes/ReferenceRect.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ReferenceRect" inherits="Control" category="Core" version="3.1-dev"> +<class name="ReferenceRect" inherits="Control" category="Core" version="3.1"> <brief_description> Reference frame for GUI. </brief_description> diff --git a/doc/classes/ReflectionProbe.xml b/doc/classes/ReflectionProbe.xml index c565fc6a92..36a0c9cfda 100644 --- a/doc/classes/ReflectionProbe.xml +++ b/doc/classes/ReflectionProbe.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ReflectionProbe" inherits="VisualInstance" category="Core" version="3.1-dev"> +<class name="ReflectionProbe" inherits="VisualInstance" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/RemoteTransform.xml b/doc/classes/RemoteTransform.xml index 16521e27ea..a7deb273b6 100644 --- a/doc/classes/RemoteTransform.xml +++ b/doc/classes/RemoteTransform.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RemoteTransform" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="RemoteTransform" inherits="Spatial" category="Core" version="3.1"> <brief_description> RemoteTransform leads the [Transform] of another [Spatial] derived Node in the scene. </brief_description> diff --git a/doc/classes/RemoteTransform2D.xml b/doc/classes/RemoteTransform2D.xml index a6c61eb2f4..bc562dcdad 100644 --- a/doc/classes/RemoteTransform2D.xml +++ b/doc/classes/RemoteTransform2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RemoteTransform2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="RemoteTransform2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> RemoteTransform2D leads the [Transform2D] of another [CanvasItem] derived Node in the scene. </brief_description> diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml index 9bba251607..fc42635ce2 100644 --- a/doc/classes/Resource.xml +++ b/doc/classes/Resource.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Resource" inherits="Reference" category="Core" version="3.1-dev"> +<class name="Resource" inherits="Reference" category="Core" version="3.1"> <brief_description> Base class for all resources. </brief_description> diff --git a/doc/classes/ResourceImporter.xml b/doc/classes/ResourceImporter.xml index 91e72ff595..09fe828bd3 100644 --- a/doc/classes/ResourceImporter.xml +++ b/doc/classes/ResourceImporter.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourceImporter" inherits="Reference" category="Core" version="3.1-dev"> +<class name="ResourceImporter" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/ResourceInteractiveLoader.xml b/doc/classes/ResourceInteractiveLoader.xml index dba045213e..076121b42d 100644 --- a/doc/classes/ResourceInteractiveLoader.xml +++ b/doc/classes/ResourceInteractiveLoader.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourceInteractiveLoader" inherits="Reference" category="Core" version="3.1-dev"> +<class name="ResourceInteractiveLoader" inherits="Reference" category="Core" version="3.1"> <brief_description> Interactive Resource Loader. </brief_description> diff --git a/doc/classes/ResourceLoader.xml b/doc/classes/ResourceLoader.xml index baeb7a6bb4..ac00c13b2f 100644 --- a/doc/classes/ResourceLoader.xml +++ b/doc/classes/ResourceLoader.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourceLoader" inherits="Object" category="Core" version="3.1-dev"> +<class name="ResourceLoader" inherits="Object" category="Core" version="3.1"> <brief_description> Resource Loader. </brief_description> diff --git a/doc/classes/ResourcePreloader.xml b/doc/classes/ResourcePreloader.xml index 6c3c4cd5d0..002bcd891a 100644 --- a/doc/classes/ResourcePreloader.xml +++ b/doc/classes/ResourcePreloader.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourcePreloader" inherits="Node" category="Core" version="3.1-dev"> +<class name="ResourcePreloader" inherits="Node" category="Core" version="3.1"> <brief_description> Resource Preloader Node. </brief_description> diff --git a/doc/classes/ResourceSaver.xml b/doc/classes/ResourceSaver.xml index e44244aabb..ae0d8e909d 100644 --- a/doc/classes/ResourceSaver.xml +++ b/doc/classes/ResourceSaver.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourceSaver" inherits="Object" category="Core" version="3.1-dev"> +<class name="ResourceSaver" inherits="Object" category="Core" version="3.1"> <brief_description> Resource Saving Interface. </brief_description> diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index dab8eb1505..49bb1aed45 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RichTextLabel" inherits="Control" category="Core" version="3.1-dev"> +<class name="RichTextLabel" inherits="Control" category="Core" version="3.1"> <brief_description> Label that displays rich text. </brief_description> diff --git a/doc/classes/RigidBody.xml b/doc/classes/RigidBody.xml index a1aa479ea1..3190aed5ed 100644 --- a/doc/classes/RigidBody.xml +++ b/doc/classes/RigidBody.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RigidBody" inherits="PhysicsBody" category="Core" version="3.1-dev"> +<class name="RigidBody" inherits="PhysicsBody" category="Core" version="3.1"> <brief_description> Physics Body whose position is determined through physics simulation in 3D space. </brief_description> @@ -38,7 +38,7 @@ <method name="apply_torque_impulse"> <return type="void"> </return> - <argument index="1" name="impulse" type="Vector3"> + <argument index="0" name="impulse" type="Vector3"> </argument> <description> Apply a torque impulse (which will be affected by the body mass and shape). This will rotate the body around the passed in vector. diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml index 719ddfffe4..75fbb48454 100644 --- a/doc/classes/RigidBody2D.xml +++ b/doc/classes/RigidBody2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RigidBody2D" inherits="PhysicsBody2D" category="Core" version="3.1-dev"> +<class name="RigidBody2D" inherits="PhysicsBody2D" category="Core" version="3.1"> <brief_description> A body that is controlled by the 2D physics engine. </brief_description> @@ -66,9 +66,11 @@ </return> <argument index="0" name="motion" type="Vector2"> </argument> - <argument index="1" name="margin" type="float" default="0.08"> + <argument index="1" name="infinite_inertia" type="bool" default="true"> </argument> - <argument index="2" name="result" type="Physics2DTestMotionResult" default="null"> + <argument index="2" name="margin" type="float" default="0.08"> + </argument> + <argument index="3" name="result" type="Physics2DTestMotionResult" default="null"> </argument> <description> Returns [code]true[/code] if a collision would result from moving in the given vector. [code]margin[/code] increases the size of the shapes involved in the collision detection, and [code]result[/code] is an object of type [Physics2DTestMotionResult], which contains additional information about the collision (should there be one). diff --git a/doc/classes/SceneState.xml b/doc/classes/SceneState.xml index 3ce08c0878..36cddf08df 100644 --- a/doc/classes/SceneState.xml +++ b/doc/classes/SceneState.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SceneState" inherits="Reference" category="Core" version="3.1-dev"> +<class name="SceneState" inherits="Reference" category="Core" version="3.1"> <brief_description> A script interface to a scene file's data. </brief_description> diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index bd6ffbaf80..be90288308 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SceneTree" inherits="MainLoop" category="Core" version="3.1-dev"> +<class name="SceneTree" inherits="MainLoop" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/SceneTreeTimer.xml b/doc/classes/SceneTreeTimer.xml index a5b199d9d7..e1234ce88a 100644 --- a/doc/classes/SceneTreeTimer.xml +++ b/doc/classes/SceneTreeTimer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SceneTreeTimer" inherits="Reference" category="Core" version="3.1-dev"> +<class name="SceneTreeTimer" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Script.xml b/doc/classes/Script.xml index db85890b2b..4257991e0d 100644 --- a/doc/classes/Script.xml +++ b/doc/classes/Script.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Script" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Script" inherits="Resource" category="Core" version="3.1"> <brief_description> A class stored as a resource. </brief_description> diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml index 0b5365f583..4bfd07fdad 100644 --- a/doc/classes/ScriptEditor.xml +++ b/doc/classes/ScriptEditor.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ScriptEditor" inherits="PanelContainer" category="Core" version="3.1-dev"> +<class name="ScriptEditor" inherits="PanelContainer" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/ScrollBar.xml b/doc/classes/ScrollBar.xml index 04b3ccfca0..d3e6c62e49 100644 --- a/doc/classes/ScrollBar.xml +++ b/doc/classes/ScrollBar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ScrollBar" inherits="Range" category="Core" version="3.1-dev"> +<class name="ScrollBar" inherits="Range" category="Core" version="3.1"> <brief_description> Base class for scroll bars. </brief_description> diff --git a/doc/classes/ScrollContainer.xml b/doc/classes/ScrollContainer.xml index 3a613f8bcd..79b70fec99 100644 --- a/doc/classes/ScrollContainer.xml +++ b/doc/classes/ScrollContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ScrollContainer" inherits="Container" category="Core" version="3.1-dev"> +<class name="ScrollContainer" inherits="Container" category="Core" version="3.1"> <brief_description> A helper node for displaying scrollable elements (e.g. lists). </brief_description> diff --git a/doc/classes/SegmentShape2D.xml b/doc/classes/SegmentShape2D.xml index 69dd4f7ca2..63afb37a7b 100644 --- a/doc/classes/SegmentShape2D.xml +++ b/doc/classes/SegmentShape2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SegmentShape2D" inherits="Shape2D" category="Core" version="3.1-dev"> +<class name="SegmentShape2D" inherits="Shape2D" category="Core" version="3.1"> <brief_description> Segment shape for 2D collisions. </brief_description> diff --git a/doc/classes/Semaphore.xml b/doc/classes/Semaphore.xml index 353c621818..f3a37b78e1 100644 --- a/doc/classes/Semaphore.xml +++ b/doc/classes/Semaphore.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Semaphore" inherits="Reference" category="Core" version="3.1-dev"> +<class name="Semaphore" inherits="Reference" category="Core" version="3.1"> <brief_description> A synchronization Semaphore. </brief_description> diff --git a/doc/classes/Separator.xml b/doc/classes/Separator.xml index 725ca8d2d0..e5efa4a100 100644 --- a/doc/classes/Separator.xml +++ b/doc/classes/Separator.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Separator" inherits="Control" category="Core" version="3.1-dev"> +<class name="Separator" inherits="Control" category="Core" version="3.1"> <brief_description> Base class for separators. </brief_description> diff --git a/doc/classes/Shader.xml b/doc/classes/Shader.xml index f9f26593bf..732881c777 100644 --- a/doc/classes/Shader.xml +++ b/doc/classes/Shader.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Shader" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Shader" inherits="Resource" category="Core" version="3.1"> <brief_description> To be changed, ignore. </brief_description> diff --git a/doc/classes/ShaderMaterial.xml b/doc/classes/ShaderMaterial.xml index 57fb3ed1aa..4767686a8f 100644 --- a/doc/classes/ShaderMaterial.xml +++ b/doc/classes/ShaderMaterial.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ShaderMaterial" inherits="Material" category="Core" version="3.1-dev"> +<class name="ShaderMaterial" inherits="Material" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Shape.xml b/doc/classes/Shape.xml index 240da1a43d..582e4f80c3 100644 --- a/doc/classes/Shape.xml +++ b/doc/classes/Shape.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Shape" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Shape" inherits="Resource" category="Core" version="3.1"> <brief_description> Base class for all 3D shape resources. </brief_description> diff --git a/doc/classes/Shape2D.xml b/doc/classes/Shape2D.xml index 0f3fc44ecb..ad20bf607a 100644 --- a/doc/classes/Shape2D.xml +++ b/doc/classes/Shape2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Shape2D" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Shape2D" inherits="Resource" category="Core" version="3.1"> <brief_description> Base class for all 2D Shapes. </brief_description> diff --git a/doc/classes/ShortCut.xml b/doc/classes/ShortCut.xml index 2cb832c045..6da9d7c59d 100644 --- a/doc/classes/ShortCut.xml +++ b/doc/classes/ShortCut.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ShortCut" inherits="Resource" category="Core" version="3.1-dev"> +<class name="ShortCut" inherits="Resource" category="Core" version="3.1"> <brief_description> A shortcut for binding input. </brief_description> diff --git a/doc/classes/Skeleton.xml b/doc/classes/Skeleton.xml index 760b2e92a9..0208d56cfa 100644 --- a/doc/classes/Skeleton.xml +++ b/doc/classes/Skeleton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Skeleton" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="Skeleton" inherits="Spatial" category="Core" version="3.1"> <brief_description> Skeleton for characters and animated objects. </brief_description> diff --git a/doc/classes/Sky.xml b/doc/classes/Sky.xml index 4f3593dfcb..245da99084 100644 --- a/doc/classes/Sky.xml +++ b/doc/classes/Sky.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Sky" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Sky" inherits="Resource" category="Core" version="3.1"> <brief_description> The base class for [PanoramaSky] and [ProceduralSky]. </brief_description> diff --git a/doc/classes/Slider.xml b/doc/classes/Slider.xml index aa19a27735..554842b50e 100644 --- a/doc/classes/Slider.xml +++ b/doc/classes/Slider.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Slider" inherits="Range" category="Core" version="3.1-dev"> +<class name="Slider" inherits="Range" category="Core" version="3.1"> <brief_description> Base class for GUI Sliders. </brief_description> diff --git a/doc/classes/SliderJoint.xml b/doc/classes/SliderJoint.xml index d8e4970363..edb8e6d562 100644 --- a/doc/classes/SliderJoint.xml +++ b/doc/classes/SliderJoint.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SliderJoint" inherits="Joint" category="Core" version="3.1-dev"> +<class name="SliderJoint" inherits="Joint" category="Core" version="3.1"> <brief_description> Piston kind of slider between two bodies in 3D. </brief_description> diff --git a/doc/classes/Spatial.xml b/doc/classes/Spatial.xml index b142e5c96c..822a699984 100644 --- a/doc/classes/Spatial.xml +++ b/doc/classes/Spatial.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Spatial" inherits="Node" category="Core" version="3.1-dev"> +<class name="Spatial" inherits="Node" category="Core" version="3.1"> <brief_description> Most basic 3D game object, parent of all 3D related nodes. </brief_description> diff --git a/doc/classes/SpatialGizmo.xml b/doc/classes/SpatialGizmo.xml index fde79e19dd..68d1d03296 100644 --- a/doc/classes/SpatialGizmo.xml +++ b/doc/classes/SpatialGizmo.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SpatialGizmo" inherits="Reference" category="Core" version="3.1-dev"> +<class name="SpatialGizmo" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/SpatialMaterial.xml b/doc/classes/SpatialMaterial.xml index ce67ddc220..ace1aa846e 100644 --- a/doc/classes/SpatialMaterial.xml +++ b/doc/classes/SpatialMaterial.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SpatialMaterial" inherits="Material" category="Core" version="3.1-dev"> +<class name="SpatialMaterial" inherits="Material" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/SpatialVelocityTracker.xml b/doc/classes/SpatialVelocityTracker.xml index 8d666c9f84..45cc4232dc 100644 --- a/doc/classes/SpatialVelocityTracker.xml +++ b/doc/classes/SpatialVelocityTracker.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SpatialVelocityTracker" inherits="Reference" category="Core" version="3.1-dev"> +<class name="SpatialVelocityTracker" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/SphereMesh.xml b/doc/classes/SphereMesh.xml index 72af6137d0..e0e2d10408 100644 --- a/doc/classes/SphereMesh.xml +++ b/doc/classes/SphereMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SphereMesh" inherits="PrimitiveMesh" category="Core" version="3.1-dev"> +<class name="SphereMesh" inherits="PrimitiveMesh" category="Core" version="3.1"> <brief_description> Class representing a spherical [PrimitiveMesh]. </brief_description> diff --git a/doc/classes/SphereShape.xml b/doc/classes/SphereShape.xml index cb2461942d..bc0cd79ddd 100644 --- a/doc/classes/SphereShape.xml +++ b/doc/classes/SphereShape.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SphereShape" inherits="Shape" category="Core" version="3.1-dev"> +<class name="SphereShape" inherits="Shape" category="Core" version="3.1"> <brief_description> Sphere shape for 3D collisions. </brief_description> diff --git a/doc/classes/SpinBox.xml b/doc/classes/SpinBox.xml index 76dcfa97f6..0fcd5bbaf5 100644 --- a/doc/classes/SpinBox.xml +++ b/doc/classes/SpinBox.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SpinBox" inherits="Range" category="Core" version="3.1-dev"> +<class name="SpinBox" inherits="Range" category="Core" version="3.1"> <brief_description> Numerical input text field. </brief_description> diff --git a/doc/classes/SplitContainer.xml b/doc/classes/SplitContainer.xml index 54cfaaff63..692598f382 100644 --- a/doc/classes/SplitContainer.xml +++ b/doc/classes/SplitContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SplitContainer" inherits="Container" category="Core" version="3.1-dev"> +<class name="SplitContainer" inherits="Container" category="Core" version="3.1"> <brief_description> Container for splitting and adjusting. </brief_description> diff --git a/doc/classes/SpotLight.xml b/doc/classes/SpotLight.xml index 88e3240188..57a802d325 100644 --- a/doc/classes/SpotLight.xml +++ b/doc/classes/SpotLight.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SpotLight" inherits="Light" category="Core" version="3.1-dev"> +<class name="SpotLight" inherits="Light" category="Core" version="3.1"> <brief_description> Spotlight [Light], such as a reflector spotlight or a lantern. </brief_description> diff --git a/doc/classes/Sprite.xml b/doc/classes/Sprite.xml index d60e1dbe52..dd7fe010ba 100644 --- a/doc/classes/Sprite.xml +++ b/doc/classes/Sprite.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Sprite" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="Sprite" inherits="Node2D" category="Core" version="3.1"> <brief_description> General purpose Sprite node. </brief_description> @@ -11,6 +11,13 @@ <demos> </demos> <methods> + <method name="get_rect" qualifiers="const"> + <return type="Rect2"> + </return> + <description> + Returns a Rect2 representing the Sprite's boundary relative to its local coordinates. + </description> + </method> </methods> <members> <member name="centered" type="bool" setter="set_centered" getter="is_centered"> @@ -26,7 +33,7 @@ Current frame to display from sprite sheet. [member vframes] or [member hframes] must be greater than 1. </member> <member name="hframes" type="int" setter="set_hframes" getter="get_hframes"> - The number of collumns in the sprite sheet. + The number of columns in the sprite sheet. </member> <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map"> The normal map gives depth to the Sprite. diff --git a/doc/classes/Sprite3D.xml b/doc/classes/Sprite3D.xml index 122f0b85f7..2a65246dde 100644 --- a/doc/classes/Sprite3D.xml +++ b/doc/classes/Sprite3D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Sprite3D" inherits="SpriteBase3D" category="Core" version="3.1-dev"> +<class name="Sprite3D" inherits="SpriteBase3D" category="Core" version="3.1"> <brief_description> 2D Sprite node in 3D world. </brief_description> diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml index 6dba815255..5eb4eb09af 100644 --- a/doc/classes/SpriteBase3D.xml +++ b/doc/classes/SpriteBase3D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SpriteBase3D" inherits="GeometryInstance" category="Core" version="3.1-dev"> +<class name="SpriteBase3D" inherits="GeometryInstance" category="Core" version="3.1"> <brief_description> 2D Sprite node in 3D environment. </brief_description> diff --git a/doc/classes/SpriteFrames.xml b/doc/classes/SpriteFrames.xml index e7199d7163..e806547b7d 100644 --- a/doc/classes/SpriteFrames.xml +++ b/doc/classes/SpriteFrames.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SpriteFrames" inherits="Resource" category="Core" version="3.1-dev"> +<class name="SpriteFrames" inherits="Resource" category="Core" version="3.1"> <brief_description> Sprite frame library for AnimatedSprite. </brief_description> diff --git a/doc/classes/StaticBody.xml b/doc/classes/StaticBody.xml index df56330c08..26b4857670 100644 --- a/doc/classes/StaticBody.xml +++ b/doc/classes/StaticBody.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StaticBody" inherits="PhysicsBody" category="Core" version="3.1-dev"> +<class name="StaticBody" inherits="PhysicsBody" category="Core" version="3.1"> <brief_description> Static body for 3D Physics. </brief_description> diff --git a/doc/classes/StaticBody2D.xml b/doc/classes/StaticBody2D.xml index ca12699061..95acda79df 100644 --- a/doc/classes/StaticBody2D.xml +++ b/doc/classes/StaticBody2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StaticBody2D" inherits="PhysicsBody2D" category="Core" version="3.1-dev"> +<class name="StaticBody2D" inherits="PhysicsBody2D" category="Core" version="3.1"> <brief_description> Static body for 2D Physics. </brief_description> diff --git a/doc/classes/StreamPeer.xml b/doc/classes/StreamPeer.xml index 4ab83f8d8a..ebe29c7e24 100644 --- a/doc/classes/StreamPeer.xml +++ b/doc/classes/StreamPeer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StreamPeer" inherits="Reference" category="Core" version="3.1-dev"> +<class name="StreamPeer" inherits="Reference" category="Core" version="3.1"> <brief_description> Abstraction and base class for stream-based protocols. </brief_description> diff --git a/doc/classes/StreamPeerBuffer.xml b/doc/classes/StreamPeerBuffer.xml index a3c118ec60..3d9bdce762 100644 --- a/doc/classes/StreamPeerBuffer.xml +++ b/doc/classes/StreamPeerBuffer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StreamPeerBuffer" inherits="StreamPeer" category="Core" version="3.1-dev"> +<class name="StreamPeerBuffer" inherits="StreamPeer" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/StreamPeerSSL.xml b/doc/classes/StreamPeerSSL.xml index 32459efd47..d7350ac1d5 100644 --- a/doc/classes/StreamPeerSSL.xml +++ b/doc/classes/StreamPeerSSL.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StreamPeerSSL" inherits="StreamPeer" category="Core" version="3.1-dev"> +<class name="StreamPeerSSL" inherits="StreamPeer" category="Core" version="3.1"> <brief_description> SSL Stream peer. </brief_description> diff --git a/doc/classes/StreamPeerTCP.xml b/doc/classes/StreamPeerTCP.xml index ef856551bb..5fc8e99ced 100644 --- a/doc/classes/StreamPeerTCP.xml +++ b/doc/classes/StreamPeerTCP.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StreamPeerTCP" inherits="StreamPeer" category="Core" version="3.1-dev"> +<class name="StreamPeerTCP" inherits="StreamPeer" category="Core" version="3.1"> <brief_description> TCP Stream peer. </brief_description> diff --git a/doc/classes/StreamTexture.xml b/doc/classes/StreamTexture.xml index 7ed95ef01c..3b44d0f00f 100644 --- a/doc/classes/StreamTexture.xml +++ b/doc/classes/StreamTexture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StreamTexture" inherits="Texture" category="Core" version="3.1-dev"> +<class name="StreamTexture" inherits="Texture" category="Core" version="3.1"> <brief_description> A .stex texture. </brief_description> diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 01d8dc32e6..d8d432e30f 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="String" category="Built-In Types" version="3.1-dev"> +<class name="String" category="Built-In Types" version="3.1"> <brief_description> Built-in string class. </brief_description> diff --git a/doc/classes/StyleBox.xml b/doc/classes/StyleBox.xml index 1e68d83237..dee3e6db49 100644 --- a/doc/classes/StyleBox.xml +++ b/doc/classes/StyleBox.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StyleBox" inherits="Resource" category="Core" version="3.1-dev"> +<class name="StyleBox" inherits="Resource" category="Core" version="3.1"> <brief_description> Base class for drawing stylized boxes for the UI. </brief_description> diff --git a/doc/classes/StyleBoxEmpty.xml b/doc/classes/StyleBoxEmpty.xml index b5000da265..a9eeeddd93 100644 --- a/doc/classes/StyleBoxEmpty.xml +++ b/doc/classes/StyleBoxEmpty.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StyleBoxEmpty" inherits="StyleBox" category="Core" version="3.1-dev"> +<class name="StyleBoxEmpty" inherits="StyleBox" category="Core" version="3.1"> <brief_description> Empty stylebox (does not display anything). </brief_description> diff --git a/doc/classes/StyleBoxFlat.xml b/doc/classes/StyleBoxFlat.xml index a64ca31ff0..641d6214a4 100644 --- a/doc/classes/StyleBoxFlat.xml +++ b/doc/classes/StyleBoxFlat.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StyleBoxFlat" inherits="StyleBox" category="Core" version="3.1-dev"> +<class name="StyleBoxFlat" inherits="StyleBox" category="Core" version="3.1"> <brief_description> Customizable Stylebox with a given set of parameters. (no texture required) </brief_description> diff --git a/doc/classes/StyleBoxLine.xml b/doc/classes/StyleBoxLine.xml index 9fa2790a4b..c891c8cf83 100644 --- a/doc/classes/StyleBoxLine.xml +++ b/doc/classes/StyleBoxLine.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StyleBoxLine" inherits="StyleBox" category="Core" version="3.1-dev"> +<class name="StyleBoxLine" inherits="StyleBox" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/StyleBoxTexture.xml b/doc/classes/StyleBoxTexture.xml index 6245400943..d8c378fde2 100644 --- a/doc/classes/StyleBoxTexture.xml +++ b/doc/classes/StyleBoxTexture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="StyleBoxTexture" inherits="StyleBox" category="Core" version="3.1-dev"> +<class name="StyleBoxTexture" inherits="StyleBox" category="Core" version="3.1"> <brief_description> Texture Based 3x3 scale style. </brief_description> @@ -59,11 +59,11 @@ </member> <member name="modulate_color" type="Color" setter="set_modulate" getter="get_modulate"> </member> - <member name="normal_map" type="Resource" setter="set_normal_map" getter="get_normal_map"> + <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map"> </member> <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect"> </member> - <member name="texture" type="Resource" setter="set_texture" getter="get_texture"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> </member> </members> <signals> diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index 71cfc9bb9a..d8644c5419 100644 --- a/doc/classes/SurfaceTool.xml +++ b/doc/classes/SurfaceTool.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SurfaceTool" inherits="Reference" category="Core" version="3.1-dev"> +<class name="SurfaceTool" inherits="Reference" category="Core" version="3.1"> <brief_description> Helper tool to create geometry. </brief_description> diff --git a/doc/classes/TCP_Server.xml b/doc/classes/TCP_Server.xml index cac81f8e05..4e3544ce5c 100644 --- a/doc/classes/TCP_Server.xml +++ b/doc/classes/TCP_Server.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TCP_Server" inherits="Reference" category="Core" version="3.1-dev"> +<class name="TCP_Server" inherits="Reference" category="Core" version="3.1"> <brief_description> TCP Server. </brief_description> diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml index eb3b270938..330487adf7 100644 --- a/doc/classes/TabContainer.xml +++ b/doc/classes/TabContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TabContainer" inherits="Control" category="Core" version="3.1-dev"> +<class name="TabContainer" inherits="Control" category="Core" version="3.1"> <brief_description> Tabbed Container. </brief_description> diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml index 7c3e28ec3c..615bc83c2d 100644 --- a/doc/classes/Tabs.xml +++ b/doc/classes/Tabs.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Tabs" inherits="Control" category="Core" version="3.1-dev"> +<class name="Tabs" inherits="Control" category="Core" version="3.1"> <brief_description> Tabs Control. </brief_description> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index c39baa8a8c..8a71cb2059 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TextEdit" inherits="Control" category="Core" version="3.1-dev"> +<class name="TextEdit" inherits="Control" category="Core" version="3.1"> <brief_description> Multiline text editing control. </brief_description> diff --git a/doc/classes/Texture.xml b/doc/classes/Texture.xml index 997324992a..3d3ceca150 100644 --- a/doc/classes/Texture.xml +++ b/doc/classes/Texture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Texture" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Texture" inherits="Resource" category="Core" version="3.1"> <brief_description> Texture for 2D and 3D. </brief_description> diff --git a/doc/classes/TextureButton.xml b/doc/classes/TextureButton.xml index 1f9c6acb47..7e54ab9fe8 100644 --- a/doc/classes/TextureButton.xml +++ b/doc/classes/TextureButton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TextureButton" inherits="BaseButton" category="Core" version="3.1-dev"> +<class name="TextureButton" inherits="BaseButton" category="Core" version="3.1"> <brief_description> Texture-based button. Supports Pressed, Hover, Disabled and Focused states. </brief_description> diff --git a/doc/classes/TextureProgress.xml b/doc/classes/TextureProgress.xml index 3c4ed13746..18bd886b0b 100644 --- a/doc/classes/TextureProgress.xml +++ b/doc/classes/TextureProgress.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TextureProgress" inherits="Range" category="Core" version="3.1-dev"> +<class name="TextureProgress" inherits="Range" category="Core" version="3.1"> <brief_description> Texture-based progress bar. Useful for loading screens and life or stamina bars. </brief_description> diff --git a/doc/classes/TextureRect.xml b/doc/classes/TextureRect.xml index 8d18adcc36..7a4208ccea 100644 --- a/doc/classes/TextureRect.xml +++ b/doc/classes/TextureRect.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TextureRect" inherits="Control" category="Core" version="3.1-dev"> +<class name="TextureRect" inherits="Control" category="Core" version="3.1"> <brief_description> Draws a sprite or a texture inside a User Interface. The texture can tile or not. </brief_description> diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml index 4134936764..fe43b54d5e 100644 --- a/doc/classes/Theme.xml +++ b/doc/classes/Theme.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Theme" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Theme" inherits="Resource" category="Core" version="3.1"> <brief_description> Theme for controls. </brief_description> diff --git a/doc/classes/Thread.xml b/doc/classes/Thread.xml index c5aac8f1ce..48d075c7f5 100644 --- a/doc/classes/Thread.xml +++ b/doc/classes/Thread.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Thread" inherits="Reference" category="Core" version="3.1-dev"> +<class name="Thread" inherits="Reference" category="Core" version="3.1"> <brief_description> A unit of execution in a process. </brief_description> diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index 0a5fc1951b..6ee9489995 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TileMap" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="TileMap" inherits="Node2D" category="Core" version="3.1"> <brief_description> Node for 2D tile-based maps. </brief_description> @@ -19,6 +19,13 @@ Clear all cells. </description> </method> + <method name="fix_invalid_tiles"> + <return type="void"> + </return> + <description> + Clear cells that does not exist in the tileset. + </description> + </method> <method name="get_cell" qualifiers="const"> <return type="int"> </return> diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml index 3b9a34abff..10978970e9 100644 --- a/doc/classes/TileSet.xml +++ b/doc/classes/TileSet.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TileSet" inherits="Resource" category="Core" version="3.1-dev"> +<class name="TileSet" inherits="Resource" category="Core" version="3.1"> <brief_description> Tile library for tilemaps. </brief_description> diff --git a/doc/classes/Timer.xml b/doc/classes/Timer.xml index 892b14a933..aba1b78188 100644 --- a/doc/classes/Timer.xml +++ b/doc/classes/Timer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Timer" inherits="Node" category="Core" version="3.1-dev"> +<class name="Timer" inherits="Node" category="Core" version="3.1"> <brief_description> A countdown timer. </brief_description> diff --git a/doc/classes/ToolButton.xml b/doc/classes/ToolButton.xml index 916585ecf7..1dbfd63010 100644 --- a/doc/classes/ToolButton.xml +++ b/doc/classes/ToolButton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ToolButton" inherits="Button" category="Core" version="3.1-dev"> +<class name="ToolButton" inherits="Button" category="Core" version="3.1"> <brief_description> Flat button helper class. </brief_description> diff --git a/doc/classes/TouchScreenButton.xml b/doc/classes/TouchScreenButton.xml index 50bb23f5d9..1b37ce95ba 100644 --- a/doc/classes/TouchScreenButton.xml +++ b/doc/classes/TouchScreenButton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TouchScreenButton" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="TouchScreenButton" inherits="Node2D" category="Core" version="3.1"> <brief_description> Button for touch screen devices. </brief_description> diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml index 2ebdea9d5e..df5c2ab3ae 100644 --- a/doc/classes/Transform.xml +++ b/doc/classes/Transform.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Transform" category="Built-In Types" version="3.1-dev"> +<class name="Transform" category="Built-In Types" version="3.1"> <brief_description> 3D Transformation. 3x4 matrix. </brief_description> diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml index 11b8b37ebd..d5427ad7f8 100644 --- a/doc/classes/Transform2D.xml +++ b/doc/classes/Transform2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Transform2D" category="Built-In Types" version="3.1-dev"> +<class name="Transform2D" category="Built-In Types" version="3.1"> <brief_description> 2D Transformation. 3x2 matrix. </brief_description> diff --git a/doc/classes/Translation.xml b/doc/classes/Translation.xml index d3964b8f02..c4e9dbfb70 100644 --- a/doc/classes/Translation.xml +++ b/doc/classes/Translation.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Translation" inherits="Resource" category="Core" version="3.1-dev"> +<class name="Translation" inherits="Resource" category="Core" version="3.1"> <brief_description> Language Translation. </brief_description> diff --git a/doc/classes/TranslationServer.xml b/doc/classes/TranslationServer.xml index a95ae9b2a3..52d2b2cc47 100644 --- a/doc/classes/TranslationServer.xml +++ b/doc/classes/TranslationServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TranslationServer" inherits="Object" category="Core" version="3.1-dev"> +<class name="TranslationServer" inherits="Object" category="Core" version="3.1"> <brief_description> Server that manages all translations. Translations can be set to it and removed from it. </brief_description> diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index 7e8cc1179c..25426ee72c 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Tree" inherits="Control" category="Core" version="3.1-dev"> +<class name="Tree" inherits="Control" category="Core" version="3.1"> <brief_description> Control to show a tree of items. </brief_description> diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index 21b3223cd3..6448b26972 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TreeItem" inherits="Object" category="Core" version="3.1-dev"> +<class name="TreeItem" inherits="Object" category="Core" version="3.1"> <brief_description> Control for a single item inside a [Tree]. </brief_description> diff --git a/doc/classes/TriangleMesh.xml b/doc/classes/TriangleMesh.xml index a55130744f..2bdc7b61f4 100644 --- a/doc/classes/TriangleMesh.xml +++ b/doc/classes/TriangleMesh.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="TriangleMesh" inherits="Reference" category="Core" version="3.1-dev"> +<class name="TriangleMesh" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml index dabf8a59b3..54e445d3ee 100644 --- a/doc/classes/Tween.xml +++ b/doc/classes/Tween.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Tween" inherits="Node" category="Core" version="3.1-dev"> +<class name="Tween" inherits="Node" category="Core" version="3.1"> <brief_description> Node useful for animations with unknown start and end points. </brief_description> diff --git a/doc/classes/UndoRedo.xml b/doc/classes/UndoRedo.xml index 13f0a506da..a1a6d7f465 100644 --- a/doc/classes/UndoRedo.xml +++ b/doc/classes/UndoRedo.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="UndoRedo" inherits="Object" category="Core" version="3.1-dev"> +<class name="UndoRedo" inherits="Object" category="Core" version="3.1"> <brief_description> Helper to manage UndoRedo in the editor or custom tools. </brief_description> diff --git a/doc/classes/VBoxContainer.xml b/doc/classes/VBoxContainer.xml index d1eb013f29..43a7be74c3 100644 --- a/doc/classes/VBoxContainer.xml +++ b/doc/classes/VBoxContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VBoxContainer" inherits="BoxContainer" category="Core" version="3.1-dev"> +<class name="VBoxContainer" inherits="BoxContainer" category="Core" version="3.1"> <brief_description> Vertical box container. </brief_description> diff --git a/doc/classes/VScrollBar.xml b/doc/classes/VScrollBar.xml index 9958b40027..5486140870 100644 --- a/doc/classes/VScrollBar.xml +++ b/doc/classes/VScrollBar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VScrollBar" inherits="ScrollBar" category="Core" version="3.1-dev"> +<class name="VScrollBar" inherits="ScrollBar" category="Core" version="3.1"> <brief_description> Vertical version of [ScrollBar], which goes from left (min) to right (max). </brief_description> diff --git a/doc/classes/VSeparator.xml b/doc/classes/VSeparator.xml index 2b7027076c..4890b2d930 100644 --- a/doc/classes/VSeparator.xml +++ b/doc/classes/VSeparator.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VSeparator" inherits="Separator" category="Core" version="3.1-dev"> +<class name="VSeparator" inherits="Separator" category="Core" version="3.1"> <brief_description> Vertical version of [Separator]. </brief_description> diff --git a/doc/classes/VSlider.xml b/doc/classes/VSlider.xml index 404626c32d..1dc1b795f7 100644 --- a/doc/classes/VSlider.xml +++ b/doc/classes/VSlider.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VSlider" inherits="Slider" category="Core" version="3.1-dev"> +<class name="VSlider" inherits="Slider" category="Core" version="3.1"> <brief_description> Vertical slider. </brief_description> diff --git a/doc/classes/VSplitContainer.xml b/doc/classes/VSplitContainer.xml index 903539fd54..2203035db3 100644 --- a/doc/classes/VSplitContainer.xml +++ b/doc/classes/VSplitContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VSplitContainer" inherits="SplitContainer" category="Core" version="3.1-dev"> +<class name="VSplitContainer" inherits="SplitContainer" category="Core" version="3.1"> <brief_description> Vertical split container. </brief_description> diff --git a/doc/classes/Variant.xml b/doc/classes/Variant.xml index 27e6799fd4..b2d21921a1 100644 --- a/doc/classes/Variant.xml +++ b/doc/classes/Variant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Variant" category="Core" version="3.1-dev"> +<class name="Variant" category="Core" version="3.1"> <brief_description> The most important data type in Godot. </brief_description> diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index 7666425e86..b293ec3368 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Vector2" category="Built-In Types" version="3.1-dev"> +<class name="Vector2" category="Built-In Types" version="3.1"> <brief_description> Vector used for 2D Math. </brief_description> @@ -81,6 +81,15 @@ Returns the vector with a maximum length. </description> </method> + <method name="cross"> + <return type="float"> + </return> + <argument index="0" name="b" type="Vector2"> + </argument> + <description> + Returns the 2-dimensional analog of the cross product with [code]b[/code]. + </description> + </method> <method name="cubic_interpolate"> <return type="Vector2"> </return> diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index 09afa17282..940d4dd6cf 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Vector3" category="Built-In Types" version="3.1-dev"> +<class name="Vector3" category="Built-In Types" version="3.1"> <brief_description> Vector class, which performs basic 3D vector math operations. </brief_description> diff --git a/doc/classes/VehicleBody.xml b/doc/classes/VehicleBody.xml index f5ec98ea04..3ce0cadde9 100644 --- a/doc/classes/VehicleBody.xml +++ b/doc/classes/VehicleBody.xml @@ -1,8 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VehicleBody" inherits="RigidBody" category="Core" version="3.1-dev"> +<class name="VehicleBody" inherits="RigidBody" category="Core" version="3.1"> <brief_description> + Physics body that simulates the behaviour of a car. </brief_description> <description> + This nodes implements all the physics logic needed to simulate a car. It is based on the raycast vehicle system commonly found in physics engines. You will need to add a [CollisionShape] for the main body of your vehicle and add [VehicleWheel] nodes for the wheels. You should also add a [MeshInstance] to this node for the 3D model of your car but this model should not include meshes for the wheels. You should control the vehicle by using the [member brake], [member engine_force], and [member steering] properties and not change the position or orientation of this node directly. + Note that the origin point of your VehicleBody will determine the center of gravity of your vehicle so it is better to keep this low and move the [CollisionShape] and [MeshInstance] upwards. </description> <tutorials> </tutorials> @@ -12,10 +15,14 @@ </methods> <members> <member name="brake" type="float" setter="set_brake" getter="get_brake"> + Slows down the vehicle by applying a braking force. The vehicle is only slowed down if the wheels are in contact with a surface. The force you need to apply to adequately slow down your vehicle depends on the [member RigidBody.mass] of the vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 30 range for hard braking. </member> <member name="engine_force" type="float" setter="set_engine_force" getter="get_engine_force"> + Accelerates the vehicle by applying an engine force. The vehicle is only speed up if the wheels that have [member VehicleWheel.set_use_as_traction] set to true and are in contact with a surface. The [member RigidBody.mass] of the vehicle has an effect on the acceleration of the vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 range for acceleration. Note that the simulation does not take the effect of gears into account, you will need to add logic for this if you wish to simulate gears. + A negative value will result in the vehicle reversing. </member> <member name="steering" type="float" setter="set_steering" getter="get_steering"> + The steering angle for the vehicle. Setting this to a non-zero value will result in the vehicle turning when it's moving. Wheels that have [member VehicleWheel.set_use_as_steering] set to true will automatically be rotated. </member> </members> <constants> diff --git a/doc/classes/VehicleWheel.xml b/doc/classes/VehicleWheel.xml index 16b2424b6e..f2c6f5f287 100644 --- a/doc/classes/VehicleWheel.xml +++ b/doc/classes/VehicleWheel.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VehicleWheel" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="VehicleWheel" inherits="Spatial" category="Core" version="3.1"> <brief_description> + Physics object that simulates the behaviour of a wheel. </brief_description> <description> + This node needs to be used as a child node of [VehicleBody] and simulates the behaviour of one of its wheels. This node also acts as a collider to detect if the wheel is touching a surface. </description> <tutorials> </tutorials> @@ -13,37 +15,51 @@ <return type="float"> </return> <description> + Returns a value between 0.0 and 1.0 that indicates whether this wheel is skidding. 0.0 is not skidding, 1.0 means the wheel has lost grip. </description> </method> <method name="is_in_contact" qualifiers="const"> <return type="bool"> </return> <description> + Returns true if this wheel is in contact with a surface. </description> </method> </methods> <members> <member name="damping_compression" type="float" setter="set_damping_compression" getter="get_damping_compression"> + The damping applied to the spring when the spring is being compressed. This value should be between 0.0 (no damping) and 1.0. A value of 0.0 means the car will keep bouncing as the spring keeps its energy. A good value for this is around 0.3 for a normal car, 0.5 for a race car. </member> <member name="damping_relaxation" type="float" setter="set_damping_relaxation" getter="get_damping_relaxation"> + The damping applied to the spring when relaxing. This value should be between 0.0 (no damping) and 1.0. This value should always be slightly higher than the [member damping_compression] property. For a [member damping_compression] value of 0.3, try a relaxation value of 0.5 </member> <member name="suspension_max_force" type="float" setter="set_suspension_max_force" getter="get_suspension_max_force"> + The maximum force the spring can resist. This value should be higher than a quarter of the [member RigidBody.mass] of the [VehicleBody] or the spring will not carry the weight of the vehicle. Good results are often obtained by a value that is about 3x to 4x this number. </member> <member name="suspension_stiffness" type="float" setter="set_suspension_stiffness" getter="get_suspension_stiffness"> + This value defines the stiffness of the suspension. Use a value lower than 50 for an off-road car, a value between 50 and 100 for a race car and try something around 200 for something like a Formula 1 car. </member> <member name="suspension_travel" type="float" setter="set_suspension_travel" getter="get_suspension_travel"> + This is the distance the suspension can travel. As Godot measures are in meters keep this setting relatively low. Try a value between 0.1 and 0.3 depending on the type of car . </member> <member name="use_as_steering" type="bool" setter="set_use_as_steering" getter="is_used_as_steering"> + If true this wheel will be turned when the car steers. </member> <member name="use_as_traction" type="bool" setter="set_use_as_traction" getter="is_used_as_traction"> + If true this wheel transfers engine force to the ground to propel the vehicle forward. </member> <member name="wheel_friction_slip" type="float" setter="set_friction_slip" getter="get_friction_slip"> + This determines how much grip this wheel has. It is combined with the friction setting of the surface the wheel is in contact with. 0.0 means no grip, 1.0 is normal grip. For a drift car setup, try setting the grip of the rear wheels slightly lower than the front wheels, or use a lower value to simulate tire wear. + It's best to set this to 1.0 when starting out. </member> <member name="wheel_radius" type="float" setter="set_radius" getter="get_radius"> + The radius of the wheel in meters. </member> <member name="wheel_rest_length" type="float" setter="set_suspension_rest_length" getter="get_suspension_rest_length"> + This is the distance in meters the wheel is lowered from its origin point. Don't set this to 0.0 and move the wheel into position, instead move the origin point of your wheel (the gizmo in Godot) to the position the wheel will take when bottoming out, then use the rest length to move the wheel down to the position it should be in when the car is in rest. </member> <member name="wheel_roll_influence" type="float" setter="set_roll_influence" getter="get_roll_influence"> + This value effects the roll of your vehicle. If set to 0.0 for all wheels your vehicle will be prone to rolling over while a value of 1.0 will resist body roll. </member> </members> <constants> diff --git a/doc/classes/VideoPlayer.xml b/doc/classes/VideoPlayer.xml index aa827c6e2c..48d09ccd95 100644 --- a/doc/classes/VideoPlayer.xml +++ b/doc/classes/VideoPlayer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VideoPlayer" inherits="Control" category="Core" version="3.1-dev"> +<class name="VideoPlayer" inherits="Control" category="Core" version="3.1"> <brief_description> Control to play video files. </brief_description> diff --git a/doc/classes/VideoStream.xml b/doc/classes/VideoStream.xml index c777673cf4..6bfa48511b 100644 --- a/doc/classes/VideoStream.xml +++ b/doc/classes/VideoStream.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VideoStream" inherits="Resource" category="Core" version="3.1-dev"> +<class name="VideoStream" inherits="Resource" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index b3568321ad..a485205736 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Viewport" inherits="Node" category="Core" version="3.1-dev"> +<class name="Viewport" inherits="Node" category="Core" version="3.1"> <brief_description> Creates a sub-view into the screen. </brief_description> @@ -123,7 +123,7 @@ <return type="bool"> </return> <description> - Get the enabled status of the size strech override set with [method set_size_override_stretch]. + Get the enabled status of the size stretch override set with [method set_size_override_stretch]. </description> </method> <method name="set_attach_to_screen_rect"> diff --git a/doc/classes/ViewportContainer.xml b/doc/classes/ViewportContainer.xml index 8c89a2c1be..8c60fb473d 100644 --- a/doc/classes/ViewportContainer.xml +++ b/doc/classes/ViewportContainer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ViewportContainer" inherits="Container" category="Core" version="3.1-dev"> +<class name="ViewportContainer" inherits="Container" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/ViewportTexture.xml b/doc/classes/ViewportTexture.xml index 6900c6563d..83ffc6bcfd 100644 --- a/doc/classes/ViewportTexture.xml +++ b/doc/classes/ViewportTexture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ViewportTexture" inherits="Texture" category="Core" version="3.1-dev"> +<class name="ViewportTexture" inherits="Texture" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/VisibilityEnabler.xml b/doc/classes/VisibilityEnabler.xml index 0094a9b3cc..83ba9495e5 100644 --- a/doc/classes/VisibilityEnabler.xml +++ b/doc/classes/VisibilityEnabler.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisibilityEnabler" inherits="VisibilityNotifier" category="Core" version="3.1-dev"> +<class name="VisibilityEnabler" inherits="VisibilityNotifier" category="Core" version="3.1"> <brief_description> Enable certain nodes only when visible. </brief_description> diff --git a/doc/classes/VisibilityEnabler2D.xml b/doc/classes/VisibilityEnabler2D.xml index 6b66d76733..8dfbaec6e8 100644 --- a/doc/classes/VisibilityEnabler2D.xml +++ b/doc/classes/VisibilityEnabler2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisibilityEnabler2D" inherits="VisibilityNotifier2D" category="Core" version="3.1-dev"> +<class name="VisibilityEnabler2D" inherits="VisibilityNotifier2D" category="Core" version="3.1"> <brief_description> Enable certain nodes only when visible. </brief_description> diff --git a/doc/classes/VisibilityNotifier.xml b/doc/classes/VisibilityNotifier.xml index c430a1336d..2f22dc99bf 100644 --- a/doc/classes/VisibilityNotifier.xml +++ b/doc/classes/VisibilityNotifier.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisibilityNotifier" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="VisibilityNotifier" inherits="Spatial" category="Core" version="3.1"> <brief_description> Detects when the node is visible on screen. </brief_description> diff --git a/doc/classes/VisibilityNotifier2D.xml b/doc/classes/VisibilityNotifier2D.xml index 67b3525eb4..b98f2794d2 100644 --- a/doc/classes/VisibilityNotifier2D.xml +++ b/doc/classes/VisibilityNotifier2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisibilityNotifier2D" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="VisibilityNotifier2D" inherits="Node2D" category="Core" version="3.1"> <brief_description> Detects when the node is visible on screen. </brief_description> diff --git a/doc/classes/VisualInstance.xml b/doc/classes/VisualInstance.xml index 81e1bcf7f7..502209fac5 100644 --- a/doc/classes/VisualInstance.xml +++ b/doc/classes/VisualInstance.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualInstance" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="VisualInstance" inherits="Spatial" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml index 204a4a6704..bd1a9fb3e5 100644 --- a/doc/classes/VisualServer.xml +++ b/doc/classes/VisualServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualServer" inherits="Object" category="Core" version="3.1-dev"> +<class name="VisualServer" inherits="Object" category="Core" version="3.1"> <brief_description> Server for anything visible. </brief_description> @@ -175,7 +175,9 @@ </argument> <argument index="1" name="mesh" type="RID"> </argument> - <argument index="2" name="skeleton" type="RID"> + <argument index="2" name="texture" type="RID"> + </argument> + <argument index="3" name="normal_map" type="RID"> </argument> <description> Adds a [Mesh] to the [CanvasItem]'s draw commands. Only affects its aabb at the moment. @@ -188,7 +190,9 @@ </argument> <argument index="1" name="mesh" type="RID"> </argument> - <argument index="2" name="skeleton" type="RID"> + <argument index="2" name="texture" type="RID"> + </argument> + <argument index="3" name="normal_map" type="RID"> </argument> <description> Adds a [MultiMesh] to the [CanvasItem]'s draw commands. Only affects its aabb at the moment. @@ -1274,7 +1278,7 @@ <return type="void"> </return> <description> - Syncronizes threads. + Synchronizes threads. </description> </method> <method name="free_rid"> diff --git a/doc/classes/WeakRef.xml b/doc/classes/WeakRef.xml index adaa964630..4a0f3588c2 100644 --- a/doc/classes/WeakRef.xml +++ b/doc/classes/WeakRef.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="WeakRef" inherits="Reference" category="Core" version="3.1-dev"> +<class name="WeakRef" inherits="Reference" category="Core" version="3.1"> <brief_description> Holds an [Object], but does not contribute to the reference count if the object is a reference. </brief_description> diff --git a/doc/classes/WebSocketClient.xml b/doc/classes/WebSocketClient.xml index 9c0685031c..79313c90c7 100644 --- a/doc/classes/WebSocketClient.xml +++ b/doc/classes/WebSocketClient.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="WebSocketClient" inherits="WebSocketMultiplayerPeer" category="Core" version="3.1-dev"> +<class name="WebSocketClient" inherits="WebSocketMultiplayerPeer" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/WebSocketMultiplayerPeer.xml b/doc/classes/WebSocketMultiplayerPeer.xml index b49d4c48e0..a1014350f5 100644 --- a/doc/classes/WebSocketMultiplayerPeer.xml +++ b/doc/classes/WebSocketMultiplayerPeer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="WebSocketMultiplayerPeer" inherits="NetworkedMultiplayerPeer" category="Core" version="3.1-dev"> +<class name="WebSocketMultiplayerPeer" inherits="NetworkedMultiplayerPeer" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/WebSocketPeer.xml b/doc/classes/WebSocketPeer.xml index fba8322889..276249e65a 100644 --- a/doc/classes/WebSocketPeer.xml +++ b/doc/classes/WebSocketPeer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="WebSocketPeer" inherits="PacketPeer" category="Core" version="3.1-dev"> +<class name="WebSocketPeer" inherits="PacketPeer" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/WebSocketServer.xml b/doc/classes/WebSocketServer.xml index 887df696ff..9a7108952f 100644 --- a/doc/classes/WebSocketServer.xml +++ b/doc/classes/WebSocketServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="WebSocketServer" inherits="WebSocketMultiplayerPeer" category="Core" version="3.1-dev"> +<class name="WebSocketServer" inherits="WebSocketMultiplayerPeer" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/doc/classes/WindowDialog.xml b/doc/classes/WindowDialog.xml index ef4f6196b5..39487f5020 100644 --- a/doc/classes/WindowDialog.xml +++ b/doc/classes/WindowDialog.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="WindowDialog" inherits="Popup" category="Core" version="3.1-dev"> +<class name="WindowDialog" inherits="Popup" category="Core" version="3.1"> <brief_description> Base class for window dialogs. </brief_description> diff --git a/doc/classes/World.xml b/doc/classes/World.xml index 810e659c74..9fc0e139b5 100644 --- a/doc/classes/World.xml +++ b/doc/classes/World.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="World" inherits="Resource" category="Core" version="3.1-dev"> +<class name="World" inherits="Resource" category="Core" version="3.1"> <brief_description> Class that has everything pertaining to a world. </brief_description> diff --git a/doc/classes/World2D.xml b/doc/classes/World2D.xml index acde276c1d..5f6a5b8ad4 100644 --- a/doc/classes/World2D.xml +++ b/doc/classes/World2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="World2D" inherits="Resource" category="Core" version="3.1-dev"> +<class name="World2D" inherits="Resource" category="Core" version="3.1"> <brief_description> Class that has everything pertaining to a 2D world. </brief_description> diff --git a/doc/classes/WorldEnvironment.xml b/doc/classes/WorldEnvironment.xml index 266f94c317..422ca3a558 100644 --- a/doc/classes/WorldEnvironment.xml +++ b/doc/classes/WorldEnvironment.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="WorldEnvironment" inherits="Node" category="Core" version="3.1-dev"> +<class name="WorldEnvironment" inherits="Node" category="Core" version="3.1"> <brief_description> Default environment properties for the entire scene (post-processing effects, lightning and background settings). </brief_description> diff --git a/doc/classes/XMLParser.xml b/doc/classes/XMLParser.xml index 8855adec22..fb03ab1692 100644 --- a/doc/classes/XMLParser.xml +++ b/doc/classes/XMLParser.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="XMLParser" inherits="Reference" category="Core" version="3.1-dev"> +<class name="XMLParser" inherits="Reference" category="Core" version="3.1"> <brief_description> Low-level class for creating parsers for XML files. </brief_description> diff --git a/doc/classes/YSort.xml b/doc/classes/YSort.xml index fdccfaf531..12b9cb623f 100644 --- a/doc/classes/YSort.xml +++ b/doc/classes/YSort.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="YSort" inherits="Node2D" category="Core" version="3.1-dev"> +<class name="YSort" inherits="Node2D" category="Core" version="3.1"> <brief_description> Sort all child nodes based on their Y positions. </brief_description> diff --git a/doc/classes/bool.xml b/doc/classes/bool.xml index ed95da869b..0fec8eb530 100644 --- a/doc/classes/bool.xml +++ b/doc/classes/bool.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="bool" category="Built-In Types" version="3.1-dev"> +<class name="bool" category="Built-In Types" version="3.1"> <brief_description> Boolean built-in type </brief_description> diff --git a/doc/classes/float.xml b/doc/classes/float.xml index c576c27687..ef3c3d72eb 100644 --- a/doc/classes/float.xml +++ b/doc/classes/float.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="float" category="Built-In Types" version="3.1-dev"> +<class name="float" category="Built-In Types" version="3.1"> <brief_description> Float built-in type </brief_description> diff --git a/doc/classes/int.xml b/doc/classes/int.xml index a86353e97e..4855fa2848 100644 --- a/doc/classes/int.xml +++ b/doc/classes/int.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="int" category="Built-In Types" version="3.1-dev"> +<class name="int" category="Built-In Types" version="3.1"> <brief_description> Integer built-in type. </brief_description> diff --git a/doc/tools/makemd.py b/doc/tools/makemd.py index a73a4337d0..056f1ca82d 100644 --- a/doc/tools/makemd.py +++ b/doc/tools/makemd.py @@ -93,6 +93,8 @@ def make_class_list(class_list, columns): s += '\n' f.write(s) + f.close() + def dokuize_text(txt): @@ -330,6 +332,8 @@ def make_doku_class(node): f.write('\n') f.write(dokuize_text(d.text.strip())) f.write('\n') + + f.close() for file in input_list: diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py index 9e767bf3d6..8074ce45ea 100644 --- a/doc/tools/makerst.py +++ b/doc/tools/makerst.py @@ -104,6 +104,7 @@ def make_class_list(class_list, columns): f.write("--+-------+") f.write("\n") + f.close() def rstize_text(text, cclass): # Linebreak + tabs in the XML should become two line breaks unless in a "codeblock" @@ -572,6 +573,8 @@ def make_rst_class(node): f.write("\n\n") f.write('\n') + f.close() + file_list = [] diff --git a/drivers/SCsub b/drivers/SCsub index fc017f4891..2c5e9434e8 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -24,6 +24,7 @@ if env['xaudio2']: # Graphics drivers if (env["platform"] != "server"): SConscript('gles3/SCsub') + SConscript('gles2/SCsub') SConscript('gl_context/SCsub') else: SConscript('dummy/SCsub') diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index 0bb03d23ea..1e17e72532 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -37,19 +37,20 @@ #include <errno.h> -Error AudioDriverALSA::init() { - - active = false; - thread_exited = false; - exit_thread = false; - pcm_open = false; - samples_in = NULL; - samples_out = NULL; - +Error AudioDriverALSA::init_device() { mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE); speaker_mode = SPEAKER_MODE_STEREO; channels = 2; + // If there is a specified device check that it is really present + if (device_name != "Default") { + Array list = get_device_list(); + if (list.find(device_name) == -1) { + device_name = "Default"; + new_device = "Default"; + } + } + int status; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; @@ -65,7 +66,16 @@ Error AudioDriverALSA::init() { //6 chans - "plug:surround51" //4 chans - "plug:surround40"; - status = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); + if (device_name == "Default") { + status = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); + } else { + String device = device_name; + int pos = device.find(";"); + if (pos != -1) { + device = device.substr(0, pos); + } + status = snd_pcm_open(&pcm_handle, device.utf8().get_data(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); + } ERR_FAIL_COND_V(status < 0, ERR_CANT_OPEN); @@ -129,15 +139,28 @@ Error AudioDriverALSA::init() { status = snd_pcm_sw_params(pcm_handle, swparams); CHECK_FAIL(status < 0); - samples_in = memnew_arr(int32_t, period_size * channels); - samples_out = memnew_arr(int16_t, period_size * channels); + samples_in.resize(period_size * channels); + samples_out.resize(period_size * channels); snd_pcm_nonblock(pcm_handle, 0); - mutex = Mutex::create(); - thread = Thread::create(AudioDriverALSA::thread_func, this); - return OK; +} + +Error AudioDriverALSA::init() { + + active = false; + thread_exited = false; + exit_thread = false; + pcm_open = false; + + Error err = init_device(); + if (err == OK) { + mutex = Mutex::create(); + thread = Thread::create(AudioDriverALSA::thread_func, this); + } + + return err; }; void AudioDriverALSA::thread_func(void *p_udata) { @@ -152,7 +175,7 @@ void AudioDriverALSA::thread_func(void *p_udata) { } else { ad->lock(); - ad->audio_server_process(ad->period_size, ad->samples_in); + ad->audio_server_process(ad->period_size, ad->samples_in.ptrw()); ad->unlock(); @@ -167,7 +190,7 @@ void AudioDriverALSA::thread_func(void *p_udata) { while (todo) { if (ad->exit_thread) break; - uint8_t *src = (uint8_t *)ad->samples_out; + uint8_t *src = (uint8_t *)ad->samples_out.ptr(); int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo); if (wrote < 0) { @@ -193,6 +216,26 @@ void AudioDriverALSA::thread_func(void *p_udata) { total += wrote; todo -= wrote; }; + + // User selected a new device, finish the current one so we'll init the new device + if (ad->device_name != ad->new_device) { + ad->device_name = ad->new_device; + ad->finish_device(); + + Error err = ad->init_device(); + if (err != OK) { + ERR_PRINT("ALSA: init_device error"); + ad->device_name = "Default"; + ad->new_device = "Default"; + + err = ad->init_device(); + if (err != OK) { + ad->active = false; + ad->exit_thread = true; + break; + } + } + } }; ad->thread_exited = true; @@ -213,6 +256,49 @@ AudioDriver::SpeakerMode AudioDriverALSA::get_speaker_mode() const { return speaker_mode; }; +Array AudioDriverALSA::get_device_list() { + + Array list; + + list.push_back("Default"); + + void **hints; + + if (snd_device_name_hint(-1, "pcm", &hints) < 0) + return list; + + for (void **n = hints; *n != NULL; n++) { + char *name = snd_device_name_get_hint(*n, "NAME"); + char *desc = snd_device_name_get_hint(*n, "DESC"); + + if (name != NULL && !strncmp(name, "plughw", 6)) { + if (desc) { + list.push_back(String(name) + ";" + String(desc)); + } else { + list.push_back(String(name)); + } + } + + if (desc != NULL) + free(desc); + if (name != NULL) + free(name); + } + snd_device_name_free_hint(hints); + + return list; +} + +String AudioDriverALSA::get_device() { + + return device_name; +} + +void AudioDriverALSA::set_device(String device) { + + new_device = device; +} + void AudioDriverALSA::lock() { if (!thread || !mutex) @@ -227,6 +313,14 @@ void AudioDriverALSA::unlock() { mutex->unlock(); }; +void AudioDriverALSA::finish_device() { + + if (pcm_open) { + snd_pcm_close(pcm_handle); + pcm_open = NULL; + } +} + void AudioDriverALSA::finish() { if (!thread) @@ -235,17 +329,13 @@ void AudioDriverALSA::finish() { exit_thread = true; Thread::wait_to_finish(thread); - if (pcm_open) - snd_pcm_close(pcm_handle); - - if (samples_in) { - memdelete_arr(samples_in); - memdelete_arr(samples_out); - }; + finish_device(); memdelete(thread); - if (mutex) + if (mutex) { memdelete(mutex); + mutex = NULL; + } thread = NULL; }; @@ -254,6 +344,9 @@ AudioDriverALSA::AudioDriverALSA() { mutex = NULL; thread = NULL; pcm_handle = NULL; + + device_name = "Default"; + new_device = "Default"; }; AudioDriverALSA::~AudioDriverALSA(){ diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h index 8ed60dfdc7..2878e100a2 100644 --- a/drivers/alsa/audio_driver_alsa.h +++ b/drivers/alsa/audio_driver_alsa.h @@ -44,8 +44,14 @@ class AudioDriverALSA : public AudioDriver { snd_pcm_t *pcm_handle; - int32_t *samples_in; - int16_t *samples_out; + String device_name; + String new_device; + + Vector<int32_t> samples_in; + Vector<int16_t> samples_out; + + Error init_device(); + void finish_device(); static void thread_func(void *p_udata); @@ -71,6 +77,9 @@ public: virtual void start(); virtual int get_mix_rate() const; virtual SpeakerMode get_speaker_mode() const; + virtual Array get_device_list(); + virtual String get_device(); + virtual void set_device(String device); virtual void lock(); virtual void unlock(); virtual void finish(); diff --git a/drivers/convex_decomp/b2d_decompose.cpp b/drivers/convex_decomp/b2d_decompose.cpp index d1f7a4d3c3..14456144a6 100644 --- a/drivers/convex_decomp/b2d_decompose.cpp +++ b/drivers/convex_decomp/b2d_decompose.cpp @@ -94,7 +94,7 @@ static Vector<Vector<Vector2> > _b2d_decompose(const Vector<Vector2> &p_polygon) float32 dot = dx0 * dx1 + dy0 * dy1; if (fabs(cross) < b2_angularSlop && dot > 0) { //Angle too close, split the triangle across from this point. - //This is guaranteed to result in two triangles that satify + //This is guaranteed to result in two triangles that satisfy //the tolerance (one of the angles is 90 degrees) float32 dx2 = curr.x[lower] - curr.x[upper]; float32 dy2 = curr.y[lower] - curr.y[upper]; diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index 0b39f9ebc3..c84469f26f 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -37,16 +37,22 @@ #define kOutputBus 0 #ifdef OSX_ENABLED -static OSStatus outputDeviceAddressCB(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inClientData) { +OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID, + UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, + void *inClientData) { AudioDriverCoreAudio *driver = (AudioDriverCoreAudio *)inClientData; - driver->reopen(); + // If our selected device is the Default call set_device to update the + // kAudioOutputUnitProperty_CurrentDevice property + if (driver->device_name == "Default") { + driver->set_device("Default"); + } return noErr; } #endif -Error AudioDriverCoreAudio::initDevice() { +Error AudioDriverCoreAudio::init_device() { AudioComponentDescription desc; zeromem(&desc, sizeof(desc)); desc.componentType = kAudioUnitType_Output; @@ -129,7 +135,7 @@ Error AudioDriverCoreAudio::initDevice() { return OK; } -Error AudioDriverCoreAudio::finishDevice() { +Error AudioDriverCoreAudio::finish_device() { OSStatus result; if (active) { @@ -153,49 +159,18 @@ Error AudioDriverCoreAudio::init() { channels = 2; #ifdef OSX_ENABLED - outputDeviceAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice; - outputDeviceAddress.mScope = kAudioObjectPropertyScopeGlobal; - outputDeviceAddress.mElement = kAudioObjectPropertyElementMaster; + AudioObjectPropertyAddress prop; + prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice; + prop.mScope = kAudioObjectPropertyScopeGlobal; + prop.mElement = kAudioObjectPropertyElementMaster; - result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this); + result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this); ERR_FAIL_COND_V(result != noErr, FAILED); #endif - return initDevice(); + return init_device(); }; -Error AudioDriverCoreAudio::reopen() { - bool restart = false; - - lock(); - - if (active) { - restart = true; - } - - Error err = finishDevice(); - if (err != OK) { - ERR_PRINT("finishDevice failed"); - unlock(); - return err; - } - - err = initDevice(); - if (err != OK) { - ERR_PRINT("initDevice failed"); - unlock(); - return err; - } - - if (restart) { - start(); - } - - unlock(); - - return OK; -} - OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, @@ -257,6 +232,150 @@ AudioDriver::SpeakerMode AudioDriverCoreAudio::get_speaker_mode() const { return get_speaker_mode_by_total_channels(channels); }; +#ifdef OSX_ENABLED + +Array AudioDriverCoreAudio::get_device_list() { + + Array list; + + list.push_back("Default"); + + AudioObjectPropertyAddress prop; + + prop.mSelector = kAudioHardwarePropertyDevices; + prop.mScope = kAudioObjectPropertyScopeGlobal; + prop.mElement = kAudioObjectPropertyElementMaster; + + UInt32 size = 0; + AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &prop, 0, NULL, &size); + AudioDeviceID *audioDevices = (AudioDeviceID *)malloc(size); + AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop, 0, NULL, &size, audioDevices); + + UInt32 deviceCount = size / sizeof(AudioDeviceID); + for (UInt32 i = 0; i < deviceCount; i++) { + prop.mScope = kAudioDevicePropertyScopeOutput; + prop.mSelector = kAudioDevicePropertyStreamConfiguration; + + AudioObjectGetPropertyDataSize(audioDevices[i], &prop, 0, NULL, &size); + AudioBufferList *bufferList = (AudioBufferList *)malloc(size); + AudioObjectGetPropertyData(audioDevices[i], &prop, 0, NULL, &size, bufferList); + + UInt32 outputChannelCount = 0; + for (UInt32 j = 0; j < bufferList->mNumberBuffers; j++) + outputChannelCount += bufferList->mBuffers[j].mNumberChannels; + + free(bufferList); + + if (outputChannelCount >= 1) { + CFStringRef cfname; + + size = sizeof(CFStringRef); + prop.mSelector = kAudioObjectPropertyName; + + AudioObjectGetPropertyData(audioDevices[i], &prop, 0, NULL, &size, &cfname); + + CFIndex length = CFStringGetLength(cfname); + CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1; + char *buffer = (char *)malloc(maxSize); + if (CFStringGetCString(cfname, buffer, maxSize, kCFStringEncodingUTF8)) { + // Append the ID to the name in case we have devices with duplicate name + list.push_back(String(buffer) + " (" + itos(audioDevices[i]) + ")"); + } + + free(buffer); + } + } + + free(audioDevices); + + return list; +} + +String AudioDriverCoreAudio::get_device() { + + return device_name; +} + +void AudioDriverCoreAudio::set_device(String device) { + + device_name = device; + if (!active) { + return; + } + + AudioDeviceID deviceId; + bool found = false; + if (device_name != "Default") { + AudioObjectPropertyAddress prop; + + prop.mSelector = kAudioHardwarePropertyDevices; + prop.mScope = kAudioObjectPropertyScopeGlobal; + prop.mElement = kAudioObjectPropertyElementMaster; + + UInt32 size = 0; + AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &prop, 0, NULL, &size); + AudioDeviceID *audioDevices = (AudioDeviceID *)malloc(size); + AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop, 0, NULL, &size, audioDevices); + + UInt32 deviceCount = size / sizeof(AudioDeviceID); + for (UInt32 i = 0; i < deviceCount && !found; i++) { + prop.mScope = kAudioDevicePropertyScopeOutput; + prop.mSelector = kAudioDevicePropertyStreamConfiguration; + + AudioObjectGetPropertyDataSize(audioDevices[i], &prop, 0, NULL, &size); + AudioBufferList *bufferList = (AudioBufferList *)malloc(size); + AudioObjectGetPropertyData(audioDevices[i], &prop, 0, NULL, &size, bufferList); + + UInt32 outputChannelCount = 0; + for (UInt32 j = 0; j < bufferList->mNumberBuffers; j++) + outputChannelCount += bufferList->mBuffers[j].mNumberChannels; + + free(bufferList); + + if (outputChannelCount >= 1) { + CFStringRef cfname; + + size = sizeof(CFStringRef); + prop.mSelector = kAudioObjectPropertyName; + + AudioObjectGetPropertyData(audioDevices[i], &prop, 0, NULL, &size, &cfname); + + CFIndex length = CFStringGetLength(cfname); + CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1; + char *buffer = (char *)malloc(maxSize); + if (CFStringGetCString(cfname, buffer, maxSize, kCFStringEncodingUTF8)) { + String name = String(buffer) + " (" + itos(audioDevices[i]) + ")"; + if (name == device_name) { + deviceId = audioDevices[i]; + found = true; + } + } + + free(buffer); + } + } + + free(audioDevices); + } + + if (!found) { + UInt32 size = sizeof(AudioDeviceID); + AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + + OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, NULL, &size, &deviceId); + ERR_FAIL_COND(result != noErr); + + found = true; + } + + if (found) { + OSStatus result = AudioUnitSetProperty(audio_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID)); + ERR_FAIL_COND(result != noErr); + } +} + +#endif + void AudioDriverCoreAudio::lock() { if (mutex) mutex->lock(); @@ -276,10 +395,15 @@ bool AudioDriverCoreAudio::try_lock() { void AudioDriverCoreAudio::finish() { OSStatus result; - finishDevice(); + finish_device(); #ifdef OSX_ENABLED - result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this); + AudioObjectPropertyAddress prop; + prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice; + prop.mScope = kAudioObjectPropertyScopeGlobal; + prop.mElement = kAudioObjectPropertyElementMaster; + + result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this); if (result != noErr) { ERR_PRINT("AudioObjectRemovePropertyListener failed"); } @@ -309,6 +433,8 @@ AudioDriverCoreAudio::AudioDriverCoreAudio() { buffer_frames = 0; samples_in.clear(); + + device_name = "Default"; }; AudioDriverCoreAudio::~AudioDriverCoreAudio(){}; diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h index 51256085d8..1ef474ac19 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.h +++ b/drivers/coreaudio/audio_driver_coreaudio.h @@ -43,12 +43,12 @@ class AudioDriverCoreAudio : public AudioDriver { AudioComponentInstance audio_unit; -#ifdef OSX_ENABLED - AudioObjectPropertyAddress outputDeviceAddress; -#endif + bool active; Mutex *mutex; + String device_name; + int mix_rate; unsigned int channels; unsigned int buffer_frames; @@ -56,14 +56,18 @@ class AudioDriverCoreAudio : public AudioDriver { Vector<int32_t> samples_in; + static OSStatus output_device_address_cb(AudioObjectID inObjectID, + UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, + void *inClientData); + static OSStatus output_callback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); - Error initDevice(); - Error finishDevice(); + Error init_device(); + Error finish_device(); public: const char *get_name() const { @@ -74,12 +78,16 @@ public: virtual void start(); virtual int get_mix_rate() const; virtual SpeakerMode get_speaker_mode() const; +#ifdef OSX_ENABLED + virtual Array get_device_list(); + virtual String get_device(); + virtual void set_device(String device); +#endif virtual void lock(); virtual void unlock(); virtual void finish(); bool try_lock(); - Error reopen(); AudioDriverCoreAudio(); ~AudioDriverCoreAudio(); diff --git a/drivers/dummy/audio_driver_dummy.h b/drivers/dummy/audio_driver_dummy.h index c3d8e10767..b3f0fcee07 100644 --- a/drivers/dummy/audio_driver_dummy.h +++ b/drivers/dummy/audio_driver_dummy.h @@ -43,13 +43,13 @@ public: virtual Error init() { return OK; } virtual void start(){}; - virtual int get_mix_rate() const {}; - virtual SpeakerMode get_speaker_mode() const {}; + virtual int get_mix_rate() const { return DEFAULT_MIX_RATE; }; + virtual SpeakerMode get_speaker_mode() const { return SPEAKER_MODE_STEREO; }; virtual void lock(){}; virtual void unlock(){}; virtual void finish(){}; - virtual float get_latency(){}; + virtual float get_latency() { return 0; }; AudioDriverDummy(){}; ~AudioDriverDummy(){}; diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h index 4a7b8fd3a4..ea0d3ec706 100644 --- a/drivers/dummy/rasterizer_dummy.h +++ b/drivers/dummy/rasterizer_dummy.h @@ -269,7 +269,10 @@ public: PoolVector<uint8_t> p; return p; } - PoolVector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const {} + PoolVector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const { + PoolVector<uint8_t> p; + return p; + } uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const { return 0; } VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const { return VS::PRIMITIVE_POINTS; } @@ -301,9 +304,9 @@ public: RID multimesh_get_mesh(RID p_multimesh) const { return RID(); } - Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const {} - Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const {} - Color multimesh_instance_get_color(RID p_multimesh, int p_index) const {} + Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const { return Transform(); } + Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { return Transform2D(); } + Color multimesh_instance_get_color(RID p_multimesh, int p_index) const { return Color(); } void multimesh_set_visible_instances(RID p_multimesh, int p_visible) {} int multimesh_get_visible_instances(RID p_multimesh) const { return 0; } @@ -370,7 +373,7 @@ public: VS::LightType light_get_type(RID p_light) const { return VS::LIGHT_OMNI; } AABB light_get_aabb(RID p_light) const { return AABB(); } float light_get_param(RID p_light, VS::LightParam p_param) { return 0.0; } - Color light_get_color(RID p_light) {} + Color light_get_color(RID p_light) { return Color(); } uint64_t light_get_version(RID p_light) const { return 0; } /* PROBE API */ @@ -391,7 +394,7 @@ public: void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {} AABB reflection_probe_get_aabb(RID p_probe) const { return AABB(); } - VS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const {} + VS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const { return VisualServer::REFLECTION_PROBE_UPDATE_ONCE; } uint32_t reflection_probe_get_cull_mask(RID p_probe) const { return 0; } Vector3 reflection_probe_get_extents(RID p_probe) const { return Vector3(); } Vector3 reflection_probe_get_origin_offset(RID p_probe) const { return Vector3(); } @@ -581,7 +584,7 @@ public: RID canvas_light_occluder_create() { return RID(); } void canvas_light_occluder_set_polylines(RID p_occluder, const PoolVector<Vector2> &p_lines) {} - VS::InstanceType get_base_type(RID p_rid) const {} + VS::InstanceType get_base_type(RID p_rid) const { return VS::INSTANCE_NONE; } bool free(RID p_rid) { if (texture_owner.owns(p_rid)) { @@ -590,9 +593,10 @@ public: texture_owner.free(p_rid); memdelete(texture); } + return true; } - bool has_os_feature(const String &p_feature) const {} + bool has_os_feature(const String &p_feature) const { return false; } void update_dirty_resources() {} @@ -600,9 +604,9 @@ public: void render_info_begin_capture() {} void render_info_end_capture() {} - int get_captured_render_info(VS::RenderInfo p_info) {} + int get_captured_render_info(VS::RenderInfo p_info) { return 0; } - int get_render_info(VS::RenderInfo p_info) {} + int get_render_info(VS::RenderInfo p_info) { return 0; } static RasterizerStorage *base_singleton; @@ -619,7 +623,7 @@ public: void canvas_begin(){}; void canvas_end(){}; - void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light){}; + void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_transform){}; void canvas_debug_viewport_shadows(Light *p_lights_with_shadow){}; void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) {} diff --git a/drivers/gles2/SCsub b/drivers/gles2/SCsub new file mode 100644 index 0000000000..2471dd3739 --- /dev/null +++ b/drivers/gles2/SCsub @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +Import('env') + +env.add_source_files(env.drivers_sources,"*.cpp") + +SConscript("shaders/SCsub") diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp new file mode 100644 index 0000000000..cc8e3277b9 --- /dev/null +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -0,0 +1,1147 @@ +/*************************************************************************/ +/* rasterizer_canvas_gles2.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#include "rasterizer_canvas_gles2.h" +#include "os/os.h" +#include "project_settings.h" +#include "rasterizer_scene_gles2.h" +#include "servers/visual/visual_server_raster.h" +#ifndef GLES_OVER_GL +#define glClearDepth glClearDepthf +#endif + +RID RasterizerCanvasGLES2::light_internal_create() { + + return RID(); +} + +void RasterizerCanvasGLES2::light_internal_update(RID p_rid, Light *p_light) { +} + +void RasterizerCanvasGLES2::light_internal_free(RID p_rid) { +} + +void RasterizerCanvasGLES2::_set_uniforms() { + + state.canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX, state.uniforms.projection_matrix); + state.canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, state.uniforms.modelview_matrix); + state.canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, state.uniforms.extra_matrix); + + state.canvas_shader.set_uniform(CanvasShaderGLES2::FINAL_MODULATE, state.uniforms.final_modulate); +} + +void RasterizerCanvasGLES2::canvas_begin() { + + if (storage->frame.clear_request) { + glClearColor(storage->frame.clear_request_color.r, + storage->frame.clear_request_color.g, + storage->frame.clear_request_color.b, + storage->frame.clear_request_color.a); + glClear(GL_COLOR_BUFFER_BIT); + storage->frame.clear_request = false; + } + + if (storage->frame.current_rt) { + glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); + glColorMask(1, 1, 1, 1); + } + + reset_canvas(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); + + glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); + glDisableVertexAttribArray(VS::ARRAY_COLOR); + + // set up default uniforms + + Transform canvas_transform; + + if (storage->frame.current_rt) { + + float csy = 1.0; + if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) { + csy = -1.0; + } + canvas_transform.translate(-(storage->frame.current_rt->width / 2.0f), -(storage->frame.current_rt->height / 2.0f), 0.0f); + canvas_transform.scale(Vector3(2.0f / storage->frame.current_rt->width, csy * -2.0f / storage->frame.current_rt->height, 1.0f)); + } else { + Vector2 ssize = OS::get_singleton()->get_window_size(); + canvas_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); + canvas_transform.scale(Vector3(2.0f / ssize.width, -2.0f / ssize.height, 1.0f)); + } + + state.uniforms.projection_matrix = canvas_transform; + + state.uniforms.final_modulate = Color(1, 1, 1, 1); + + state.uniforms.modelview_matrix = Transform2D(); + state.uniforms.extra_matrix = Transform2D(); + + _set_uniforms(); + _bind_quad_buffer(); +} + +void RasterizerCanvasGLES2::canvas_end() { + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + for (int i = 0; i < VS::ARRAY_MAX; i++) { + glDisableVertexAttribArray(i); + } + + state.using_texture_rect = false; + state.using_ninepatch = false; +} + +RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map) { + + RasterizerStorageGLES2::Texture *tex_return = NULL; + + if (p_texture.is_valid()) { + + RasterizerStorageGLES2::Texture *texture = storage->texture_owner.getornull(p_texture); + + if (!texture) { + state.current_tex = RID(); + state.current_tex_ptr = NULL; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); + + } else { + + texture = texture->get_ptr(); + + if (texture->render_target) { + texture->render_target->used_in_frame = true; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture->tex_id); + + state.current_tex = p_texture; + state.current_tex_ptr = texture; + + tex_return = texture; + } + } else { + state.current_tex = RID(); + state.current_tex_ptr = NULL; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); + } + + return tex_return; +} + +void RasterizerCanvasGLES2::_set_texture_rect_mode(bool p_enable, bool p_ninepatch) { +} + +void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) { + + glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); + + uint32_t buffer_ofs = 0; + + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector2) * p_vertex_count, p_vertices); + glEnableVertexAttribArray(VS::ARRAY_VERTEX); + glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL); + buffer_ofs += sizeof(Vector2) * p_vertex_count; + + if (p_singlecolor) { + glDisableVertexAttribArray(VS::ARRAY_COLOR); + Color m = *p_colors; + glVertexAttrib4f(VS::ARRAY_COLOR, m.r, m.g, m.b, m.a); + } else if (!p_colors) { + glDisableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); + } else { + glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors); + glEnableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), ((uint8_t *)0) + buffer_ofs); + buffer_ofs += sizeof(Color) * p_vertex_count; + } + + if (p_uvs) { + glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs); + glEnableVertexAttribArray(VS::ARRAY_TEX_UV); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), ((uint8_t *)0) + buffer_ofs); + buffer_ofs += sizeof(Vector2) * p_vertex_count; + } else { + glDisableVertexAttribArray(VS::ARRAY_TEX_UV); + } + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices); + + glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_INT, 0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +void RasterizerCanvasGLES2::_draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) { + + glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); + + uint32_t buffer_ofs = 0; + + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector2) * p_vertex_count, p_vertices); + glEnableVertexAttribArray(VS::ARRAY_VERTEX); + glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), (uint8_t *)0); + buffer_ofs += sizeof(Vector2) * p_vertex_count; + + if (p_singlecolor) { + glDisableVertexAttribArray(VS::ARRAY_COLOR); + Color m = *p_colors; + glVertexAttrib4f(VS::ARRAY_COLOR, m.r, m.g, m.b, m.a); + } else if (!p_colors) { + glDisableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); + } else { + glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors); + glEnableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), ((uint8_t *)0) + buffer_ofs); + buffer_ofs += sizeof(Color) * p_vertex_count; + } + + if (p_uvs) { + glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs); + glEnableVertexAttribArray(VS::ARRAY_TEX_UV); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), ((uint8_t *)0) + buffer_ofs); + } else { + glDisableVertexAttribArray(VS::ARRAY_TEX_UV); + } + + glDrawArrays(p_primitive, 0, p_vertex_count); + + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void RasterizerCanvasGLES2::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs) { + + static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN }; + + int color_offset = 0; + int uv_offset = 0; + int stride = 2; + + if (p_colors) { + color_offset = stride; + stride += 4; + } + + if (p_uvs) { + uv_offset = stride; + stride += 2; + } + + float buffer_data[(2 + 2 + 4) * 4]; + + for (int i = 0; i < p_points; i++) { + buffer_data[stride * i + 0] = p_vertices[i].x; + buffer_data[stride * i + 1] = p_vertices[i].y; + } + + if (p_colors) { + for (int i = 0; i < p_points; i++) { + buffer_data[stride * i + color_offset + 0] = p_colors[i].r; + buffer_data[stride * i + color_offset + 1] = p_colors[i].g; + buffer_data[stride * i + color_offset + 2] = p_colors[i].b; + buffer_data[stride * i + color_offset + 3] = p_colors[i].a; + } + } + + if (p_uvs) { + for (int i = 0; i < p_points; i++) { + buffer_data[stride * i + uv_offset + 0] = p_uvs[i].x; + buffer_data[stride * i + uv_offset + 1] = p_uvs[i].y; + } + } + + glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); + glBufferSubData(GL_ARRAY_BUFFER, 0, p_points * stride * 4 * sizeof(float), buffer_data); + + glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), NULL); + + if (p_colors) { + glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), (uint8_t *)0 + color_offset * sizeof(float)); + glEnableVertexAttribArray(VS::ARRAY_COLOR); + } + + if (p_uvs) { + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), (uint8_t *)0 + uv_offset * sizeof(float)); + glEnableVertexAttribArray(VS::ARRAY_TEX_UV); + } + + glDrawArrays(prim[p_points], 0, p_points); + + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip) { + + int command_count = p_item->commands.size(); + Item::Command **commands = p_item->commands.ptrw(); + + for (int i = 0; i < command_count; i++) { + + Item::Command *command = commands[i]; + + switch (command->type) { + + case Item::Command::TYPE_LINE: { + + Item::CommandLine *line = static_cast<Item::CommandLine *>(command); + + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false); + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false); + state.canvas_shader.bind(); + + _set_uniforms(); + + _bind_canvas_texture(RID(), RID()); + + glDisableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttrib4fv(VS::ARRAY_COLOR, line->color.components); + + state.canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, state.uniforms.modelview_matrix); + + if (line->width <= 1) { + Vector2 verts[2] = { + Vector2(line->from.x, line->from.y), + Vector2(line->to.x, line->to.y) + }; + + _draw_gui_primitive(2, verts, NULL, NULL); + } else { + Vector2 t = (line->from - line->to).normalized().tangent() * line->width * 0.5; + + Vector2 verts[4] = { + line->from - t, + line->from + t, + line->to + t, + line->to - t + }; + + _draw_gui_primitive(4, verts, NULL, NULL); + } + + } break; + + case Item::Command::TYPE_RECT: { + + Item::CommandRect *r = static_cast<Item::CommandRect *>(command); + + glDisableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttrib4fv(VS::ARRAY_COLOR, r->modulate.components); + + _bind_quad_buffer(); + + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true); + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false); + if (state.canvas_shader.bind()) + _set_uniforms(); + + RasterizerStorageGLES2::Texture *tex = _bind_canvas_texture(r->texture, r->normal_map); + + if (!tex) { + Rect2 dst_rect = Rect2(r->rect.position, r->rect.size); + + if (dst_rect.size.width < 0) { + dst_rect.position.x += dst_rect.size.width; + dst_rect.size.width *= -1; + } + if (dst_rect.size.height < 0) { + dst_rect.position.y += dst_rect.size.height; + dst_rect.size.height *= -1; + } + + state.canvas_shader.set_uniform(CanvasShaderGLES2::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES2::SRC_RECT, Color(0, 0, 1, 1)); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } else { + + bool untile = false; + + if (r->flags & CANVAS_RECT_TILE && !(tex->flags & VS::TEXTURE_FLAG_REPEAT)) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + untile = true; + } + + Size2 texpixel_size(1.0 / tex->width, 1.0 / tex->height); + Rect2 src_rect = (r->flags & CANVAS_RECT_REGION) ? Rect2(r->source.position * texpixel_size, r->source.size * texpixel_size) : Rect2(0, 0, 1, 1); + + Rect2 dst_rect = Rect2(r->rect.position, r->rect.size); + + state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, texpixel_size); + + if (dst_rect.size.width < 0) { + dst_rect.position.x += dst_rect.size.width; + dst_rect.size.width *= -1; + } + if (dst_rect.size.height < 0) { + dst_rect.position.y += dst_rect.size.height; + dst_rect.size.height *= -1; + } + + if (r->flags & CANVAS_RECT_FLIP_H) { + src_rect.size.x *= -1; + } + + if (r->flags & CANVAS_RECT_FLIP_V) { + src_rect.size.y *= -1; + } + + if (r->flags & CANVAS_RECT_TRANSPOSE) { + dst_rect.size.x *= -1; // Encoding in the dst_rect.z uniform + } + + state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, texpixel_size); + + state.canvas_shader.set_uniform(CanvasShaderGLES2::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES2::SRC_RECT, Color(src_rect.position.x, src_rect.position.y, src_rect.size.x, src_rect.size.y)); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + if (untile) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + } break; + + case Item::Command::TYPE_NINEPATCH: { + + Item::CommandNinePatch *np = static_cast<Item::CommandNinePatch *>(command); + + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false); + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, true); + if (state.canvas_shader.bind()) + _set_uniforms(); + + glDisableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttrib4fv(VS::ARRAY_COLOR, np->color.components); + + RasterizerStorageGLES2::Texture *tex = _bind_canvas_texture(np->texture, np->normal_map); + + if (!tex) { + print_line("TODO: ninepatch without texture"); + continue; + } + + Size2 texpixel_size(1.0 / tex->width, 1.0 / tex->height); + + // state.canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, state.uniforms.modelview_matrix); + state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, texpixel_size); + + // prepare vertex buffer + + float buffer[16 * 2 + 16 * 2]; + + { + + // first row + + buffer[(0 * 4 * 4) + 0] = np->rect.position.x; + buffer[(0 * 4 * 4) + 1] = np->rect.position.y; + + buffer[(0 * 4 * 4) + 2] = np->source.position.x * texpixel_size.x; + buffer[(0 * 4 * 4) + 3] = np->source.position.y * texpixel_size.y; + + buffer[(0 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT]; + buffer[(0 * 4 * 4) + 5] = np->rect.position.y; + + buffer[(0 * 4 * 4) + 6] = (np->source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x; + buffer[(0 * 4 * 4) + 7] = np->source.position.y * texpixel_size.y; + + buffer[(0 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT]; + buffer[(0 * 4 * 4) + 9] = np->rect.position.y; + + buffer[(0 * 4 * 4) + 10] = (np->source.position.x + np->source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x; + buffer[(0 * 4 * 4) + 11] = np->source.position.y * texpixel_size.y; + + buffer[(0 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x; + buffer[(0 * 4 * 4) + 13] = np->rect.position.y; + + buffer[(0 * 4 * 4) + 14] = (np->source.position.x + np->source.size.x) * texpixel_size.x; + buffer[(0 * 4 * 4) + 15] = np->source.position.y * texpixel_size.y; + + // second row + + buffer[(1 * 4 * 4) + 0] = np->rect.position.x; + buffer[(1 * 4 * 4) + 1] = np->rect.position.y + np->margin[MARGIN_TOP]; + + buffer[(1 * 4 * 4) + 2] = np->source.position.x * texpixel_size.x; + buffer[(1 * 4 * 4) + 3] = (np->source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y; + + buffer[(1 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT]; + buffer[(1 * 4 * 4) + 5] = np->rect.position.y + np->margin[MARGIN_TOP]; + + buffer[(1 * 4 * 4) + 6] = (np->source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x; + buffer[(1 * 4 * 4) + 7] = (np->source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y; + + buffer[(1 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT]; + buffer[(1 * 4 * 4) + 9] = np->rect.position.y + np->margin[MARGIN_TOP]; + + buffer[(1 * 4 * 4) + 10] = (np->source.position.x + np->source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x; + buffer[(1 * 4 * 4) + 11] = (np->source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y; + + buffer[(1 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x; + buffer[(1 * 4 * 4) + 13] = np->rect.position.y + np->margin[MARGIN_TOP]; + + buffer[(1 * 4 * 4) + 14] = (np->source.position.x + np->source.size.x) * texpixel_size.x; + buffer[(1 * 4 * 4) + 15] = (np->source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y; + + // thrid row + + buffer[(2 * 4 * 4) + 0] = np->rect.position.x; + buffer[(2 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM]; + + buffer[(2 * 4 * 4) + 2] = np->source.position.x * texpixel_size.x; + buffer[(2 * 4 * 4) + 3] = (np->source.position.y + np->source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y; + + buffer[(2 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT]; + buffer[(2 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM]; + + buffer[(2 * 4 * 4) + 6] = (np->source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x; + buffer[(2 * 4 * 4) + 7] = (np->source.position.y + np->source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y; + + buffer[(2 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT]; + buffer[(2 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM]; + + buffer[(2 * 4 * 4) + 10] = (np->source.position.x + np->source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x; + buffer[(2 * 4 * 4) + 11] = (np->source.position.y + np->source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y; + + buffer[(2 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x; + buffer[(2 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM]; + + buffer[(2 * 4 * 4) + 14] = (np->source.position.x + np->source.size.x) * texpixel_size.x; + buffer[(2 * 4 * 4) + 15] = (np->source.position.y + np->source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y; + + // fourth row + + buffer[(3 * 4 * 4) + 0] = np->rect.position.x; + buffer[(3 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y; + + buffer[(3 * 4 * 4) + 2] = np->source.position.x * texpixel_size.x; + buffer[(3 * 4 * 4) + 3] = (np->source.position.y + np->source.size.y) * texpixel_size.y; + + buffer[(3 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT]; + buffer[(3 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y; + + buffer[(3 * 4 * 4) + 6] = (np->source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x; + buffer[(3 * 4 * 4) + 7] = (np->source.position.y + np->source.size.y) * texpixel_size.y; + + buffer[(3 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT]; + buffer[(3 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y; + + buffer[(3 * 4 * 4) + 10] = (np->source.position.x + np->source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x; + buffer[(3 * 4 * 4) + 11] = (np->source.position.y + np->source.size.y) * texpixel_size.y; + + buffer[(3 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x; + buffer[(3 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y; + + buffer[(3 * 4 * 4) + 14] = (np->source.position.x + np->source.size.x) * texpixel_size.x; + buffer[(3 * 4 * 4) + 15] = (np->source.position.y + np->source.size.y) * texpixel_size.y; + + // print_line(String::num((np->source.position.y + np->source.size.y) * texpixel_size.y)); + } + + glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * (16 + 16) * 2, buffer); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements); + + glEnableVertexAttribArray(VS::ARRAY_VERTEX); + glEnableVertexAttribArray(VS::ARRAY_TEX_UV); + + glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), NULL); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (uint8_t *)0 + (sizeof(float) * 2)); + + glDrawElements(GL_TRIANGLES, 18 * 3 - (np->draw_center ? 0 : 6), GL_UNSIGNED_BYTE, NULL); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + } break; + + case Item::Command::TYPE_CIRCLE: { + + Item::CommandCircle *circle = static_cast<Item::CommandCircle *>(command); + + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false); + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false); + + if (state.canvas_shader.bind()) + _set_uniforms(); + + static const int num_points = 32; + + Vector2 points[num_points + 1]; + points[num_points] = circle->pos; + + int indices[num_points * 3]; + + for (int i = 0; i < num_points; i++) { + points[i] = circle->pos + Vector2(Math::sin(i * Math_PI * 2.0 / num_points), Math::cos(i * Math_PI * 2.0 / num_points)) * circle->radius; + indices[i * 3 + 0] = i; + indices[i * 3 + 1] = (i + 1) % num_points; + indices[i * 3 + 2] = num_points; + } + + _bind_canvas_texture(RID(), RID()); + + _draw_polygon(indices, num_points * 3, num_points + 1, points, NULL, &circle->color, true); + } break; + + case Item::Command::TYPE_POLYGON: { + + Item::CommandPolygon *polygon = static_cast<Item::CommandPolygon *>(command); + + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false); + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, true); + + if (state.canvas_shader.bind()) + _set_uniforms(); + + RasterizerStorageGLES2::Texture *texture = _bind_canvas_texture(polygon->texture, polygon->normal_map); + + if (texture) { + Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); + state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, texpixel_size); + } + + _draw_polygon(polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); + } break; + + case Item::Command::TYPE_POLYLINE: { + Item::CommandPolyLine *pline = static_cast<Item::CommandPolyLine *>(command); + + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false); + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false); + + if (state.canvas_shader.bind()) + _set_uniforms(); + + if (pline->triangles.size()) { + _draw_generic(GL_TRIANGLE_STRIP, pline->triangles.size(), pline->triangles.ptr(), NULL, pline->triangle_colors.ptr(), pline->triangle_colors.size() == 1); + } else { + if (pline->multiline) { + int todo = pline->lines.size() / 2; + int max_per_call = data.polygon_buffer_size / (sizeof(real_t) * 4); + int offset = 0; + + while (todo) { + int to_draw = MIN(max_per_call, todo); + _draw_generic(GL_LINES, to_draw * 2, &pline->lines.ptr()[offset], NULL, pline->line_colors.size() == 1 ? pline->line_colors.ptr() : &pline->line_colors.ptr()[offset], pline->line_colors.size() == 1); + todo -= to_draw; + offset += to_draw * 2; + } + } else { + _draw_generic(GL_LINES, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); + } + } + } break; + + case Item::Command::TYPE_PRIMITIVE: { + + Item::CommandPrimitive *primitive = static_cast<Item::CommandPrimitive *>(command); + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false); + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, true); + + if (state.canvas_shader.bind()) + _set_uniforms(); + + ERR_CONTINUE(primitive->points.size() < 1); + + RasterizerStorageGLES2::Texture *texture = _bind_canvas_texture(primitive->texture, primitive->normal_map); + + if (texture) { + Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height); + state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, texpixel_size); + } + + if (primitive->colors.size() == 1 && primitive->points.size() > 1) { + Color c = primitive->colors[0]; + glVertexAttrib4f(VS::ARRAY_COLOR, c.r, c.g, c.b, c.a); + } else if (primitive->colors.empty()) { + glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); + } + + _draw_gui_primitive(primitive->points.size(), primitive->points.ptr(), primitive->colors.ptr(), primitive->uvs.ptr()); + } break; + + case Item::Command::TYPE_TRANSFORM: { + Item::CommandTransform *transform = static_cast<Item::CommandTransform *>(command); + state.uniforms.extra_matrix = transform->xform; + state.canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, state.uniforms.extra_matrix); + } break; + + case Item::Command::TYPE_PARTICLES: { + + } break; + + case Item::Command::TYPE_CLIP_IGNORE: { + + Item::CommandClipIgnore *ci = static_cast<Item::CommandClipIgnore *>(command); + if (current_clip) { + if (ci->ignore != reclip) { + if (ci->ignore) { + glDisable(GL_SCISSOR_TEST); + reclip = true; + } else { + glEnable(GL_SCISSOR_TEST); + + int x = current_clip->final_clip_rect.position.x; + int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y); + int w = current_clip->final_clip_rect.size.x; + int h = current_clip->final_clip_rect.size.y; + + glScissor(x, y, w, h); + + reclip = false; + } + } + } + + } break; + + default: { + print_line("other"); + } break; + } + } +} + +void RasterizerCanvasGLES2::_copy_texscreen(const Rect2 &p_rect) { + + // This isn't really working yet, so disabling for now. + + /* + glDisable(GL_BLEND); + + state.canvas_texscreen_used = true; + + Vector2 wh(storage->frame.current_rt->width, storage->frame.current_rt->height); + Color copy_section(p_rect.position.x / wh.x, p_rect.position.y / wh.y, p_rect.size.x / wh.x, p_rect.size.y / wh.y); + + if (p_rect != Rect2()) { + // only use section + + storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, true); + } + + + storage->shaders.copy.bind(); + storage->shaders.copy.set_uniform(CopyShaderGLES2::COPY_SECTION, copy_section); + + _bind_quad_buffer(); + + glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->copy_screen_effect.fbo); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDisableVertexAttribArray(VS::ARRAY_VERTEX); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); + + state.canvas_shader.bind(); + _bind_canvas_texture(state.current_tex, state.current_normal); + + glEnable(GL_BLEND); + */ +} + +void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) { + + Item *current_clip = NULL; + + RasterizerStorageGLES2::Shader *shader_cache = NULL; + + bool rebind_shader = true; + + Size2 rt_size = Size2(storage->frame.current_rt->width, storage->frame.current_rt->height); + + state.current_tex = RID(); + state.current_tex_ptr = NULL; + state.current_normal = RID(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); + + int last_blend_mode = -1; + + RID canvas_last_material = RID(); + + while (p_item_list) { + + Item *ci = p_item_list; + + if (current_clip != ci->final_clip_owner) { + + current_clip = ci->final_clip_owner; + + if (current_clip) { + glEnable(GL_SCISSOR_TEST); + glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); + } else { + glDisable(GL_SCISSOR_TEST); + } + } + + // TODO: copy back buffer + + if (ci->copy_back_buffer) { + if (ci->copy_back_buffer->full) { + _copy_texscreen(Rect2()); + } else { + _copy_texscreen(ci->copy_back_buffer->rect); + } + } + + Item *material_owner = ci->material_owner ? ci->material_owner : ci; + + RID material = material_owner->material; + + if (material != canvas_last_material || rebind_shader) { + + RasterizerStorageGLES2::Material *material_ptr = storage->material_owner.getornull(material); + RasterizerStorageGLES2::Shader *shader_ptr = NULL; + + if (material_ptr) { + shader_ptr = material_ptr->shader; + + if (shader_ptr && shader_ptr->mode != VS::SHADER_CANVAS_ITEM) { + shader_ptr = NULL; // not a canvas item shader, don't use. + } + } + + if (shader_ptr) { + if (shader_ptr->canvas_item.uses_screen_texture) { + _copy_texscreen(Rect2()); + } + + if (shader_ptr != shader_cache) { + + if (shader_ptr->canvas_item.uses_time) { + VisualServerRaster::redraw_request(); + } + + state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id); + state.canvas_shader.bind(); + } + + int tc = material_ptr->textures.size(); + RID *textures = material_ptr->textures.ptrw(); + + ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = shader_ptr->texture_hints.ptrw(); + + for (int i = 0; i < tc; i++) { + + glActiveTexture(GL_TEXTURE2 + i); + + RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(textures[i]); + + if (!t) { + + switch (texture_hints[i]) { + case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: + case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: { + glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); + } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: { + glBindTexture(GL_TEXTURE_2D, storage->resources.aniso_tex); + } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { + glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex); + } break; + default: { + glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); + } break; + } + + continue; + } + + t = t->get_ptr(); + + glBindTexture(t->target, t->tex_id); + } + } else { + state.canvas_shader.set_custom_shader(0); + state.canvas_shader.bind(); + } + + shader_cache = shader_ptr; + + canvas_last_material = material; + + rebind_shader = false; + } + + int blend_mode = shader_cache ? shader_cache->canvas_item.blend_mode : RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX; + bool unshaded = true || (shader_cache && blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX); + bool reclip = false; + + if (last_blend_mode != blend_mode) { + + switch (blend_mode) { + + case RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX: { + glBlendEquation(GL_FUNC_ADD); + if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + } break; + case RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_ADD: { + + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + } break; + case RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_SUB: { + + glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } break; + case RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MUL: { + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_DST_COLOR, GL_ZERO); + } break; + case RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_PMALPHA: { + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } break; + } + } + + state.uniforms.final_modulate = unshaded ? ci->final_modulate : Color(ci->final_modulate.r * p_modulate.r, ci->final_modulate.g * p_modulate.g, ci->final_modulate.b * p_modulate.b, ci->final_modulate.a * p_modulate.a); + + state.uniforms.modelview_matrix = ci->final_transform; + state.uniforms.extra_matrix = Transform2D(); + + _set_uniforms(); + + _canvas_item_render_commands(p_item_list, NULL, reclip); + + rebind_shader = true; // hacked in for now. + + if (reclip) { + glEnable(GL_SCISSOR_TEST); + glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height); + } + + p_item_list = p_item_list->next; + } + + if (current_clip) { + glDisable(GL_SCISSOR_TEST); + } +} + +void RasterizerCanvasGLES2::canvas_debug_viewport_shadows(Light *p_lights_with_shadow) { +} + +void RasterizerCanvasGLES2::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) { +} + +void RasterizerCanvasGLES2::reset_canvas() { + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_DITHER); + glEnable(GL_BLEND); + + if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + // bind the back buffer to a texture so shaders can use it. + // It should probably use texture unit -3 (as GLES3 does as well) but currently that's buggy. + // keeping this for now as there's nothing else that uses texture unit 2 + // TODO ^ + if (storage->frame.current_rt) { + glActiveTexture(GL_TEXTURE0 + 2); + glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color); + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +void RasterizerCanvasGLES2::_bind_quad_buffer() { + glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices); + glEnableVertexAttribArray(VS::ARRAY_VERTEX); + glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, NULL); +} +void RasterizerCanvasGLES2::draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src) { + + state.canvas_shader.set_uniform(CanvasShaderGLES2::DST_RECT, Color(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y)); + state.canvas_shader.set_uniform(CanvasShaderGLES2::SRC_RECT, Color(p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y)); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +} + +void RasterizerCanvasGLES2::draw_window_margins(int *black_margin, RID *black_image) { +} + +void RasterizerCanvasGLES2::initialize() { + + // quad buffer + { + glGenBuffers(1, &data.canvas_quad_vertices); + glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices); + + const float qv[8] = { + 0, 0, + 0, 1, + 1, 1, + 1, 0 + }; + + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, qv, GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + + // polygon buffer + { + uint32_t poly_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_buffer_size_kb", 128); + poly_size *= 1024; + poly_size = MAX(poly_size, (2 + 2 + 4) * 4 * sizeof(float)); + glGenBuffers(1, &data.polygon_buffer); + glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); + glBufferData(GL_ARRAY_BUFFER, poly_size, NULL, GL_DYNAMIC_DRAW); + + data.polygon_buffer_size = poly_size; + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + uint32_t index_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_index_size_kb", 128); + index_size *= 1024; // kb + glGenBuffers(1, &data.polygon_index_buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, NULL, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + + // ninepatch buffers + { + // array buffer + glGenBuffers(1, &data.ninepatch_vertices); + glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices); + + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, NULL, GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + // element buffer + glGenBuffers(1, &data.ninepatch_elements); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements); + +#define _EIDX(y, x) (y * 4 + x) + uint8_t elems[3 * 2 * 9] = { + + // first row + + _EIDX(0, 0), _EIDX(0, 1), _EIDX(1, 1), + _EIDX(1, 1), _EIDX(1, 0), _EIDX(0, 0), + + _EIDX(0, 1), _EIDX(0, 2), _EIDX(1, 2), + _EIDX(1, 2), _EIDX(1, 1), _EIDX(0, 1), + + _EIDX(0, 2), _EIDX(0, 3), _EIDX(1, 3), + _EIDX(1, 3), _EIDX(1, 2), _EIDX(0, 2), + + // second row + + _EIDX(1, 0), _EIDX(1, 1), _EIDX(2, 1), + _EIDX(2, 1), _EIDX(2, 0), _EIDX(1, 0), + + // the center one would be here, but we'll put it at the end + // so it's easier to disable the center and be able to use + // one draw call for both + + _EIDX(1, 2), _EIDX(1, 3), _EIDX(2, 3), + _EIDX(2, 3), _EIDX(2, 2), _EIDX(1, 2), + + // third row + + _EIDX(2, 0), _EIDX(2, 1), _EIDX(3, 1), + _EIDX(3, 1), _EIDX(3, 0), _EIDX(2, 0), + + _EIDX(2, 1), _EIDX(2, 2), _EIDX(3, 2), + _EIDX(3, 2), _EIDX(3, 1), _EIDX(2, 1), + + _EIDX(2, 2), _EIDX(2, 3), _EIDX(3, 3), + _EIDX(3, 3), _EIDX(3, 2), _EIDX(2, 2), + + // center field + + _EIDX(1, 1), _EIDX(1, 2), _EIDX(2, 2), + _EIDX(2, 2), _EIDX(2, 1), _EIDX(1, 1) + }; + ; +#undef _EIDX + + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elems), elems, GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + + state.canvas_shader.init(); + + state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true); + + state.canvas_shader.bind(); +} + +void RasterizerCanvasGLES2::finalize() { +} + +RasterizerCanvasGLES2::RasterizerCanvasGLES2() { +} diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h new file mode 100644 index 0000000000..4eab8c6038 --- /dev/null +++ b/drivers/gles2/rasterizer_canvas_gles2.h @@ -0,0 +1,129 @@ +/*************************************************************************/ +/* rasterizer_canvas_gles2.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#ifndef RASTERIZERCANVASGLES2_H +#define RASTERIZERCANVASGLES2_H + +#include "rasterizer_storage_gles2.h" +#include "servers/visual/rasterizer.h" + +#include "shaders/canvas.glsl.gen.h" + +// #include "shaders/canvas_shadow.glsl.gen.h" + +class RasterizerSceneGLES2; + +class RasterizerCanvasGLES2 : public RasterizerCanvas { +public: + struct Uniforms { + Transform projection_matrix; + + Transform2D modelview_matrix; + Transform2D extra_matrix; + + Color final_modulate; + + float time; + }; + + struct Data { + + GLuint canvas_quad_vertices; + GLuint polygon_buffer; + GLuint polygon_index_buffer; + + uint32_t polygon_buffer_size; + + GLuint ninepatch_vertices; + GLuint ninepatch_elements; + + } data; + + struct State { + Uniforms uniforms; + bool canvas_texscreen_used; + CanvasShaderGLES2 canvas_shader; + // CanvasShadowShaderGLES3 canvas_shadow_shader; + + bool using_texture_rect; + bool using_ninepatch; + + RID current_tex; + RID current_normal; + RasterizerStorageGLES2::Texture *current_tex_ptr; + + Transform vp; + + } state; + + typedef void Texture; + + RasterizerSceneGLES2 *scene_render; + + RasterizerStorageGLES2 *storage; + + virtual RID light_internal_create(); + virtual void light_internal_update(RID p_rid, Light *p_light); + virtual void light_internal_free(RID p_rid); + + void _set_uniforms(); + + virtual void canvas_begin(); + virtual void canvas_end(); + + _FORCE_INLINE_ void _set_texture_rect_mode(bool p_enable, bool p_ninepatch = false); + + _FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs); + _FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor); + _FORCE_INLINE_ void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor); + + _FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip); + _FORCE_INLINE_ void _copy_texscreen(const Rect2 &p_rect); + + virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform); + virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow); + + virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache); + + virtual void reset_canvas(); + + RasterizerStorageGLES2::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map); + + void _bind_quad_buffer(); + void draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src); + + void initialize(); + void finalize(); + + virtual void draw_window_margins(int *black_margin, RID *black_image); + + RasterizerCanvasGLES2(); +}; + +#endif // RASTERIZERCANVASGLES2_H diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp new file mode 100644 index 0000000000..9339167c8e --- /dev/null +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -0,0 +1,416 @@ +/*************************************************************************/ +/* rasterizer_gles2.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#include "rasterizer_gles2.h" + +#include "gl_context/context_gl.h" +#include "os/os.h" +#include "project_settings.h" +#include <string.h> + +#define _EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define _EXT_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define _EXT_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define _EXT_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define _EXT_DEBUG_SOURCE_API_ARB 0x8246 +#define _EXT_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define _EXT_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define _EXT_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define _EXT_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define _EXT_DEBUG_SOURCE_OTHER_ARB 0x824B +#define _EXT_DEBUG_TYPE_ERROR_ARB 0x824C +#define _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define _EXT_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define _EXT_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define _EXT_DEBUG_TYPE_OTHER_ARB 0x8251 +#define _EXT_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define _EXT_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define _EXT_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define _EXT_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define _EXT_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define _EXT_DEBUG_SEVERITY_LOW_ARB 0x9148 +#define _EXT_DEBUG_OUTPUT 0x92E0 + +#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED) +#define GLAPIENTRY APIENTRY +#else +#define GLAPIENTRY +#endif + +static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) { + + if (type == _EXT_DEBUG_TYPE_OTHER_ARB) + return; + + if (type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB) + return; //these are ultimately annoying, so removing for now + + char debSource[256], debType[256], debSev[256]; + if (source == _EXT_DEBUG_SOURCE_API_ARB) + strcpy(debSource, "OpenGL"); + else if (source == _EXT_DEBUG_SOURCE_WINDOW_SYSTEM_ARB) + strcpy(debSource, "Windows"); + else if (source == _EXT_DEBUG_SOURCE_SHADER_COMPILER_ARB) + strcpy(debSource, "Shader Compiler"); + else if (source == _EXT_DEBUG_SOURCE_THIRD_PARTY_ARB) + strcpy(debSource, "Third Party"); + else if (source == _EXT_DEBUG_SOURCE_APPLICATION_ARB) + strcpy(debSource, "Application"); + else if (source == _EXT_DEBUG_SOURCE_OTHER_ARB) + strcpy(debSource, "Other"); + + if (type == _EXT_DEBUG_TYPE_ERROR_ARB) + strcpy(debType, "Error"); + else if (type == _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB) + strcpy(debType, "Deprecated behavior"); + else if (type == _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB) + strcpy(debType, "Undefined behavior"); + else if (type == _EXT_DEBUG_TYPE_PORTABILITY_ARB) + strcpy(debType, "Portability"); + else if (type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB) + strcpy(debType, "Performance"); + else if (type == _EXT_DEBUG_TYPE_OTHER_ARB) + strcpy(debType, "Other"); + + if (severity == _EXT_DEBUG_SEVERITY_HIGH_ARB) + strcpy(debSev, "High"); + else if (severity == _EXT_DEBUG_SEVERITY_MEDIUM_ARB) + strcpy(debSev, "Medium"); + else if (severity == _EXT_DEBUG_SEVERITY_LOW_ARB) + strcpy(debSev, "Low"); + + String output = String() + "GL ERROR: Source: " + debSource + "\tType: " + debType + "\tID: " + itos(id) + "\tSeverity: " + debSev + "\tMessage: " + message; + + ERR_PRINTS(output); +} + +typedef void (*DEBUGPROCARB)(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const char *message, + const void *userParam); + +typedef void (*DebugMessageCallbackARB)(DEBUGPROCARB callback, const void *userParam); + +RasterizerStorage *RasterizerGLES2::get_storage() { + + return storage; +} + +RasterizerCanvas *RasterizerGLES2::get_canvas() { + + return canvas; +} + +RasterizerScene *RasterizerGLES2::get_scene() { + + return scene; +} + +void RasterizerGLES2::initialize() { + + if (OS::get_singleton()->is_stdout_verbose()) { + print_line("Using GLES2 video driver"); + } + +#ifdef GLAD_ENABLED + if (!gladLoadGL()) { + ERR_PRINT("Error initializing GLAD"); + } + +// GLVersion seems to be used for both GL and GL ES, so we need different version checks for them +#ifdef OPENGL_ENABLED // OpenGL 2.1 Profile required + if (GLVersion.major < 2) { +#else // OpenGL ES 3.0 + if (GLVersion.major < 2) { +#endif + ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 2.1 / OpenGL ES 2.0, sorry :(\n" + "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault."); + OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 2.1 / OpenGL ES 2.0, sorry :(\n" + "Godot Engine will self-destruct as soon as you acknowledge this error message.", + "Fatal error: Insufficient OpenGL / GLES driver support"); + } + +#ifdef GLES_OVER_GL + //Test GL_ARB_framebuffer_object extension + if (!GLAD_GL_ARB_framebuffer_object) { + //Try older GL_EXT_framebuffer_object extension + if (GLAD_GL_EXT_framebuffer_object) { + glIsRenderbuffer = glIsRenderbufferEXT; + glBindRenderbuffer = glBindRenderbufferEXT; + glDeleteRenderbuffers = glDeleteRenderbuffersEXT; + glGenRenderbuffers = glGenRenderbuffersEXT; + glRenderbufferStorage = glRenderbufferStorageEXT; + glGetRenderbufferParameteriv = glGetRenderbufferParameterivEXT; + glIsFramebuffer = glIsFramebufferEXT; + glBindFramebuffer = glBindFramebufferEXT; + glDeleteFramebuffers = glDeleteFramebuffersEXT; + glGenFramebuffers = glGenFramebuffersEXT; + glCheckFramebufferStatus = glCheckFramebufferStatusEXT; + glFramebufferTexture1D = glFramebufferTexture1DEXT; + glFramebufferTexture2D = glFramebufferTexture2DEXT; + glFramebufferTexture3D = glFramebufferTexture3DEXT; + glFramebufferRenderbuffer = glFramebufferRenderbufferEXT; + glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT; + glGenerateMipmap = glGenerateMipmapEXT; + } else { + ERR_PRINT("Your system's graphic drivers seem not to support GL_ARB(EXT)_framebuffer_object OpenGL extension, sorry :(\n" + "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault."); + OS::get_singleton()->alert("Your system's graphic drivers seem not to support GL_ARB(EXT)_framebuffer_object OpenGL extension, sorry :(\n" + "Godot Engine will self-destruct as soon as you acknowledge this error message.", + "Fatal error: Insufficient OpenGL / GLES driver support"); + } + } +#endif + if (true || OS::get_singleton()->is_stdout_verbose()) { + if (GLAD_GL_ARB_debug_output) { + glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + glDebugMessageCallbackARB(_gl_debug_print, NULL); + glEnable(_EXT_DEBUG_OUTPUT); + } else { + print_line("OpenGL debugging not supported!"); + } + } + +#endif // GLAD_ENABLED + + // For debugging +#ifdef GLES_OVER_GL + if (GLAD_GL_ARB_debug_output) { + glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_ERROR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); + glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); + glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); + glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PORTABILITY_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); + glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PERFORMANCE_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); + glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_OTHER_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); + /* glDebugMessageInsertARB( + GL_DEBUG_SOURCE_API_ARB, + GL_DEBUG_TYPE_OTHER_ARB, 1, + GL_DEBUG_SEVERITY_HIGH_ARB, 5, "hello"); + */ + } +#endif + + const GLubyte *renderer = glGetString(GL_RENDERER); + print_line("OpenGL ES 2.0 Renderer: " + String((const char *)renderer)); + storage->initialize(); + canvas->initialize(); + scene->initialize(); +} + +void RasterizerGLES2::begin_frame() { + uint64_t tick = OS::get_singleton()->get_ticks_usec(); + + double delta = double(tick - prev_ticks) / 1000000.0; + delta *= Engine::get_singleton()->get_time_scale(); + + time_total += delta; + + if (delta == 0) { + //to avoid hiccups + delta = 0.001; + } + + prev_ticks = tick; + + // double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs"); + // if (time_total > time_roll_over) + // time_total = 0; //roll over every day (should be customz + + storage->frame.time[0] = time_total; + storage->frame.time[1] = Math::fmod(time_total, 3600); + storage->frame.time[2] = Math::fmod(time_total, 900); + storage->frame.time[3] = Math::fmod(time_total, 60); + storage->frame.count++; + storage->frame.delta = delta; + + storage->frame.prev_tick = tick; + + storage->update_dirty_resources(); + + storage->info.render_final = storage->info.render; + storage->info.render.reset(); + + scene->iteration(); +} + +void RasterizerGLES2::set_current_render_target(RID p_render_target) { + + if (!p_render_target.is_valid() && storage->frame.current_rt && storage->frame.clear_request) { + // pending clear request. Do that first. + glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); + glClearColor(storage->frame.clear_request_color.r, + storage->frame.clear_request_color.g, + storage->frame.clear_request_color.b, + storage->frame.clear_request_color.a); + glClear(GL_COLOR_BUFFER_BIT); + } + + if (p_render_target.is_valid()) { + RasterizerStorageGLES2::RenderTarget *rt = storage->render_target_owner.getornull(p_render_target); + storage->frame.current_rt = rt; + ERR_FAIL_COND(!rt); + storage->frame.clear_request = false; + + glViewport(0, 0, rt->width, rt->height); + } else { + storage->frame.current_rt = NULL; + storage->frame.clear_request = false; + glViewport(0, 0, OS::get_singleton()->get_window_size().width, OS::get_singleton()->get_window_size().height); + glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo); + } +} + +void RasterizerGLES2::restore_render_target() { + ERR_FAIL_COND(storage->frame.current_rt == NULL); + RasterizerStorageGLES2::RenderTarget *rt = storage->frame.current_rt; + glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo); + glViewport(0, 0, rt->width, rt->height); +} + +void RasterizerGLES2::clear_render_target(const Color &p_color) { + ERR_FAIL_COND(!storage->frame.current_rt); + + storage->frame.clear_request = true; + storage->frame.clear_request_color = p_color; +} + +void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) { + + if (p_image.is_null() || p_image->empty()) + return; + + int window_w = OS::get_singleton()->get_video_mode(0).width; + int window_h = OS::get_singleton()->get_video_mode(0).height; + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, window_w, window_h); + glDisable(GL_BLEND); + glDepthMask(GL_FALSE); + glClearColor(p_color.r, p_color.g, p_color.b, p_color.a); + glClear(GL_COLOR_BUFFER_BIT); + + canvas->canvas_begin(); + + RID texture = storage->texture_create(); + storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), p_image->get_format(), VS::TEXTURE_FLAG_FILTER); + storage->texture_set_data(texture, p_image); + + Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height()); + Rect2 screenrect; + + screenrect = imgrect; + screenrect.position += ((Size2(window_w, window_h) - screenrect.size) / 2.0).floor(); + + RasterizerStorageGLES2::Texture *t = storage->texture_owner.get(texture); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, t->tex_id); + canvas->draw_generic_textured_rect(screenrect, Rect2(0, 0, 1, 1)); + glBindTexture(GL_TEXTURE_2D, 0); + canvas->canvas_end(); + + storage->free(texture); + + OS::get_singleton()->swap_buffers(); +} + +void RasterizerGLES2::blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen) { + + ERR_FAIL_COND(storage->frame.current_rt); + + RasterizerStorageGLES2::RenderTarget *rt = storage->render_target_owner.getornull(p_render_target); + ERR_FAIL_COND(!rt); + + canvas->state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true); + canvas->state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false); + + canvas->state.canvas_shader.bind(); + + canvas->canvas_begin(); + canvas->state.canvas_shader.set_uniform(CanvasShaderGLES2::BLIT_PASS, true); + glDisable(GL_BLEND); + glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, rt->color); + + // TODO normals + + canvas->draw_generic_textured_rect(p_screen_rect, Rect2(0, 0, 1, -1)); + + canvas->state.canvas_shader.set_uniform(CanvasShaderGLES2::BLIT_PASS, false); + + glBindTexture(GL_TEXTURE_2D, 0); + canvas->canvas_end(); +} + +void RasterizerGLES2::end_frame(bool p_swap_buffers) { + if (p_swap_buffers) + OS::get_singleton()->swap_buffers(); + else + glFinish(); +} + +void RasterizerGLES2::finalize() { +} + +Rasterizer *RasterizerGLES2::_create_current() { + + return memnew(RasterizerGLES2); +} + +void RasterizerGLES2::make_current() { + _create_func = _create_current; +} + +void RasterizerGLES2::register_config() { +} + +RasterizerGLES2::RasterizerGLES2() { + + storage = memnew(RasterizerStorageGLES2); + canvas = memnew(RasterizerCanvasGLES2); + scene = memnew(RasterizerSceneGLES2); + canvas->storage = storage; + canvas->scene_render = scene; + storage->canvas = canvas; + scene->storage = storage; + storage->scene = scene; + + prev_ticks = 0; + time_total = 0; +} + +RasterizerGLES2::~RasterizerGLES2() { + + memdelete(storage); + memdelete(canvas); +} diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h new file mode 100644 index 0000000000..8d57275449 --- /dev/null +++ b/drivers/gles2/rasterizer_gles2.h @@ -0,0 +1,72 @@ +/*************************************************************************/ +/* rasterizer_gles2.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#ifndef RASTERIZERGLES2_H +#define RASTERIZERGLES2_H + +#include "rasterizer_canvas_gles2.h" +#include "rasterizer_scene_gles2.h" +#include "rasterizer_storage_gles2.h" +#include "servers/visual/rasterizer.h" + +class RasterizerGLES2 : public Rasterizer { + + static Rasterizer *_create_current(); + + RasterizerStorageGLES2 *storage; + RasterizerCanvasGLES2 *canvas; + RasterizerSceneGLES2 *scene; + + uint64_t prev_ticks; + double time_total; + +public: + virtual RasterizerStorage *get_storage(); + virtual RasterizerCanvas *get_canvas(); + virtual RasterizerScene *get_scene(); + + virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale); + + virtual void initialize(); + virtual void begin_frame(); + virtual void set_current_render_target(RID p_render_target); + virtual void restore_render_target(); + virtual void clear_render_target(const Color &p_color); + virtual void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0); + virtual void end_frame(bool p_swap_buffers); + virtual void finalize(); + + static void make_current(); + + static void register_config(); + RasterizerGLES2(); + ~RasterizerGLES2(); +}; + +#endif // RASTERIZERGLES2_H diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp new file mode 100644 index 0000000000..bb39cbcbd5 --- /dev/null +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -0,0 +1,235 @@ +/*************************************************************************/ +/* rasterizer_scene_gles2.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#include "rasterizer_scene_gles2.h" +#include "math_funcs.h" +#include "os/os.h" +#include "project_settings.h" +#include "rasterizer_canvas_gles2.h" +#include "servers/visual/visual_server_raster.h" + +#ifndef GLES_OVER_GL +#define glClearDepth glClearDepthf +#endif + +/* SHADOW ATLAS API */ + +RID RasterizerSceneGLES2::shadow_atlas_create() { + + return RID(); +} + +void RasterizerSceneGLES2::shadow_atlas_set_size(RID p_atlas, int p_size) { +} + +void RasterizerSceneGLES2::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) { +} + +bool RasterizerSceneGLES2::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { + return false; +} + +void RasterizerSceneGLES2::set_directional_shadow_count(int p_count) { +} + +int RasterizerSceneGLES2::get_directional_light_shadow_size(RID p_light_intance) { + return 0; +} +////////////////////////////////////////////////////// + +RID RasterizerSceneGLES2::reflection_atlas_create() { + return RID(); +} + +void RasterizerSceneGLES2::reflection_atlas_set_size(RID p_ref_atlas, int p_size) { +} + +void RasterizerSceneGLES2::reflection_atlas_set_subdivision(RID p_ref_atlas, int p_subdiv) { +} + +//////////////////////////////////////////////////// + +RID RasterizerSceneGLES2::reflection_probe_instance_create(RID p_probe) { + return RID(); +} + +void RasterizerSceneGLES2::reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) { +} + +void RasterizerSceneGLES2::reflection_probe_release_atlas_index(RID p_instance) { +} + +bool RasterizerSceneGLES2::reflection_probe_instance_needs_redraw(RID p_instance) { + return false; +} + +bool RasterizerSceneGLES2::reflection_probe_instance_has_reflection(RID p_instance) { + return false; +} + +bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) { + return false; +} + +bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_instance) { + return false; +} + +/* ENVIRONMENT API */ + +RID RasterizerSceneGLES2::environment_create() { + + return RID(); +} + +void RasterizerSceneGLES2::environment_set_background(RID p_env, VS::EnvironmentBG p_bg) { +} + +void RasterizerSceneGLES2::environment_set_sky(RID p_env, RID p_sky) { +} + +void RasterizerSceneGLES2::environment_set_sky_custom_fov(RID p_env, float p_scale) { +} + +void RasterizerSceneGLES2::environment_set_bg_color(RID p_env, const Color &p_color) { +} + +void RasterizerSceneGLES2::environment_set_bg_energy(RID p_env, float p_energy) { +} + +void RasterizerSceneGLES2::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { +} + +void RasterizerSceneGLES2::environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy, float p_sky_contribution) { +} + +void RasterizerSceneGLES2::environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality) { +} + +void RasterizerSceneGLES2::environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality) { +} + +void RasterizerSceneGLES2::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) { +} + +void RasterizerSceneGLES2::environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) { +} + +void RasterizerSceneGLES2::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness) { +} + +void RasterizerSceneGLES2::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VisualServer::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { +} + +void RasterizerSceneGLES2::environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { +} + +void RasterizerSceneGLES2::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) { +} + +void RasterizerSceneGLES2::environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) { +} + +void RasterizerSceneGLES2::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) { +} + +void RasterizerSceneGLES2::environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) { +} + +bool RasterizerSceneGLES2::is_environment(RID p_env) { + return false; +} + +VS::EnvironmentBG RasterizerSceneGLES2::environment_get_background(RID p_env) { + return VS::ENV_BG_CLEAR_COLOR; +} + +int RasterizerSceneGLES2::environment_get_canvas_max_layer(RID p_env) { + return 0; +} + +RID RasterizerSceneGLES2::light_instance_create(RID p_light) { + return RID(); +} + +void RasterizerSceneGLES2::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) { +} + +void RasterizerSceneGLES2::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale) { +} + +void RasterizerSceneGLES2::light_instance_mark_visible(RID p_light_instance) { +} + +////////////////////// + +RID RasterizerSceneGLES2::gi_probe_instance_create() { + + return RID(); +} + +void RasterizerSceneGLES2::gi_probe_instance_set_light_data(RID p_probe, RID p_base, RID p_data) { +} +void RasterizerSceneGLES2::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) { +} + +void RasterizerSceneGLES2::gi_probe_instance_set_bounds(RID p_probe, const Vector3 &p_bounds) { +} + +//////////////////////////// +//////////////////////////// +//////////////////////////// + +void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { +} + +void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) { +} + +void RasterizerSceneGLES2::set_scene_pass(uint64_t p_pass) { +} + +bool RasterizerSceneGLES2::free(RID p_rid) { + return true; +} + +void RasterizerSceneGLES2::set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw) { +} + +void RasterizerSceneGLES2::initialize() { +} + +void RasterizerSceneGLES2::iteration() { +} + +void RasterizerSceneGLES2::finalize() { +} + +RasterizerSceneGLES2::RasterizerSceneGLES2() { +} diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h new file mode 100644 index 0000000000..99f034afed --- /dev/null +++ b/drivers/gles2/rasterizer_scene_gles2.h @@ -0,0 +1,258 @@ +/*************************************************************************/ +/* rasterizer_scene_gles2.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#ifndef RASTERIZERSCENEGLES2_H +#define RASTERIZERSCENEGLES2_H + +/* Must come before shaders or the Windows build fails... */ +#include "rasterizer_storage_gles2.h" + +#include "shaders/scene.glsl.gen.h" +/* + +#include "drivers/gles3/shaders/cube_to_dp.glsl.gen.h" +#include "drivers/gles3/shaders/effect_blur.glsl.gen.h" +#include "drivers/gles3/shaders/exposure.glsl.gen.h" +#include "drivers/gles3/shaders/resolve.glsl.gen.h" +#include "drivers/gles3/shaders/scene.glsl.gen.h" +#include "drivers/gles3/shaders/screen_space_reflection.glsl.gen.h" +#include "drivers/gles3/shaders/ssao.glsl.gen.h" +#include "drivers/gles3/shaders/ssao_blur.glsl.gen.h" +#include "drivers/gles3/shaders/ssao_minify.glsl.gen.h" +#include "drivers/gles3/shaders/subsurf_scattering.glsl.gen.h" +#include "drivers/gles3/shaders/tonemap.glsl.gen.h" + +*/ + +class RasterizerSceneGLES2 : public RasterizerScene { +public: + RasterizerStorageGLES2 *storage; + struct State { + + bool texscreen_copied; + int current_blend_mode; + float current_line_width; + int current_depth_draw; + bool current_depth_test; + GLuint current_main_tex; + + SceneShaderGLES2 scene_shader; + // CubeToDpShaderGLES3 cube_to_dp_shader; + // ResolveShaderGLES3 resolve_shader; + // ScreenSpaceReflectionShaderGLES3 ssr_shader; + // EffectBlurShaderGLES3 effect_blur_shader; + // SubsurfScatteringShaderGLES3 sss_shader; + // SsaoMinifyShaderGLES3 ssao_minify_shader; + // SsaoShaderGLES3 ssao_shader; + // SsaoBlurShaderGLES3 ssao_blur_shader; + // ExposureShaderGLES3 exposure_shader; + // TonemapShaderGLES3 tonemap_shader; + + /* + struct SceneDataUBO { + //this is a std140 compatible struct. Please read the OpenGL 3.3 Specificaiton spec before doing any changes + float projection_matrix[16]; + float inv_projection_matrix[16]; + float camera_inverse_matrix[16]; + float camera_matrix[16]; + float ambient_light_color[4]; + float bg_color[4]; + float fog_color_enabled[4]; + float fog_sun_color_amount[4]; + + float ambient_energy; + float bg_energy; + float z_offset; + float z_slope_scale; + float shadow_dual_paraboloid_render_zfar; + float shadow_dual_paraboloid_render_side; + float viewport_size[2]; + float screen_pixel_size[2]; + float shadow_atlas_pixel_size[2]; + float shadow_directional_pixel_size[2]; + + float time; + float z_far; + float reflection_multiplier; + float subsurface_scatter_width; + float ambient_occlusion_affect_light; + + uint32_t fog_depth_enabled; + float fog_depth_begin; + float fog_depth_curve; + uint32_t fog_transmit_enabled; + float fog_transmit_curve; + uint32_t fog_height_enabled; + float fog_height_min; + float fog_height_max; + float fog_height_curve; + // make sure this struct is padded to be a multiple of 16 bytes for webgl + + } ubo_data; + + GLuint scene_ubo; + + struct EnvironmentRadianceUBO { + + float transform[16]; + float ambient_contribution; + uint8_t padding[12]; + + } env_radiance_data; + + GLuint env_radiance_ubo; + + GLuint sky_verts; + GLuint sky_array; + + GLuint directional_ubo; + + GLuint spot_array_ubo; + GLuint omni_array_ubo; + GLuint reflection_array_ubo; + + GLuint immediate_buffer; + GLuint immediate_array; + + uint32_t ubo_light_size; + uint8_t *spot_array_tmp; + uint8_t *omni_array_tmp; + uint8_t *reflection_array_tmp; + + int max_ubo_lights; + int max_forward_lights_per_object; + int max_ubo_reflections; + int max_skeleton_bones; + + bool used_contact_shadows; + + int spot_light_count; + int omni_light_count; + int directional_light_count; + int reflection_probe_count; + + bool cull_front; + bool cull_disabled; + bool used_sss; + bool used_screen_texture; + bool using_contact_shadows; + + VS::ViewportDebugDraw debug_draw; + */ + } state; + + /* SHADOW ATLAS API */ + + RID shadow_atlas_create(); + void shadow_atlas_set_size(RID p_atlas, int p_size); + void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision); + bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version); + + virtual int get_directional_light_shadow_size(RID p_light_intance); + virtual void set_directional_shadow_count(int p_count); + + /* REFLECTION PROBE ATLAS API */ + + virtual RID reflection_atlas_create(); + virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_size); + virtual void reflection_atlas_set_subdivision(RID p_ref_atlas, int p_subdiv); + + /* REFLECTION CUBEMAPS */ + + /* REFLECTION PROBE INSTANCE */ + + virtual RID reflection_probe_instance_create(RID p_probe); + virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform); + virtual void reflection_probe_release_atlas_index(RID p_instance); + virtual bool reflection_probe_instance_needs_redraw(RID p_instance); + virtual bool reflection_probe_instance_has_reflection(RID p_instance); + virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas); + virtual bool reflection_probe_instance_postprocess_step(RID p_instance); + + /* ENVIRONMENT API */ + virtual RID environment_create(); + + virtual void environment_set_background(RID p_env, VS::EnvironmentBG p_bg); + virtual void environment_set_sky(RID p_env, RID p_sky); + virtual void environment_set_sky_custom_fov(RID p_env, float p_scale); + virtual void environment_set_bg_color(RID p_env, const Color &p_color); + virtual void environment_set_bg_energy(RID p_env, float p_energy); + virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer); + virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0); + + virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality); + virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality); + virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale); + virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture); + + virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness); + virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness); + + virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); + + virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp); + + virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount); + virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve); + virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve); + + virtual bool is_environment(RID p_env); + + virtual VS::EnvironmentBG environment_get_background(RID p_env); + virtual int environment_get_canvas_max_layer(RID p_env); + + /* LIGHT INSTANCE */ + virtual RID light_instance_create(RID p_light); + virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform); + virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0); + virtual void light_instance_mark_visible(RID p_light_instance); + + /* REFLECTION INSTANCE */ + + virtual RID gi_probe_instance_create(); + virtual void gi_probe_instance_set_light_data(RID p_probe, RID p_base, RID p_data); + virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform); + virtual void gi_probe_instance_set_bounds(RID p_probe, const Vector3 &p_bounds); + + /* RENDER LIST */ + + virtual void render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass); + virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count); + virtual bool free(RID p_rid); + + virtual void set_scene_pass(uint64_t p_pass); + virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw); + + void iteration(); + void initialize(); + void finalize(); + RasterizerSceneGLES2(); +}; + +#endif // RASTERIZERSCENEGLES2_H diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp new file mode 100644 index 0000000000..5bca3ee548 --- /dev/null +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -0,0 +1,2061 @@ +/*************************************************************************/ +/* rasterizer_storage_gles2.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#include "rasterizer_storage_gles2.h" +#include "project_settings.h" +#include "rasterizer_canvas_gles2.h" +#include "rasterizer_scene_gles2.h" + +GLuint RasterizerStorageGLES2::system_fbo = 0; + +/* TEXTURE API */ + +Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type) { + + r_gl_format = 0; + Ref<Image> image = p_image; + + bool need_decompress = false; + + switch (p_format) { + + case Image::FORMAT_L8: { + + r_gl_internal_format = GL_LUMINANCE; + r_gl_format = GL_LUMINANCE; + r_gl_type = GL_UNSIGNED_BYTE; + } break; + case Image::FORMAT_LA8: { + r_gl_internal_format = GL_LUMINANCE_ALPHA; + r_gl_format = GL_LUMINANCE_ALPHA; + r_gl_type = GL_UNSIGNED_BYTE; + } break; + case Image::FORMAT_R8: { + + r_gl_internal_format = GL_ALPHA; + r_gl_format = GL_ALPHA; + r_gl_type = GL_UNSIGNED_BYTE; + + } break; + case Image::FORMAT_RG8: { + + ERR_EXPLAIN("RG texture not supported"); + ERR_FAIL_V(image); + + } break; + case Image::FORMAT_RGB8: { + + r_gl_internal_format = GL_RGB; + r_gl_format = GL_RGB; + r_gl_type = GL_UNSIGNED_BYTE; + + } break; + case Image::FORMAT_RGBA8: { + + r_gl_format = GL_RGBA; + r_gl_internal_format = GL_RGBA; + r_gl_type = GL_UNSIGNED_BYTE; + + } break; + case Image::FORMAT_RGBA4444: { + + r_gl_internal_format = GL_RGBA; + r_gl_format = GL_RGBA; + r_gl_type = GL_UNSIGNED_SHORT_4_4_4_4; + + } break; + case Image::FORMAT_RGBA5551: { + + r_gl_internal_format = GL_RGB5_A1; + r_gl_format = GL_RGBA; + r_gl_type = GL_UNSIGNED_SHORT_5_5_5_1; + + } break; + case Image::FORMAT_RF: { + ERR_EXPLAIN("R float texture not supported"); + ERR_FAIL_V(image); + + } break; + case Image::FORMAT_RGF: { + ERR_EXPLAIN("RG float texture not supported"); + ERR_FAIL_V(image); + + } break; + case Image::FORMAT_RGBF: { + + ERR_EXPLAIN("RGB float texture not supported"); + ERR_FAIL_V(image); + + } break; + case Image::FORMAT_RGBAF: { + + ERR_EXPLAIN("RGBA float texture not supported"); + ERR_FAIL_V(image); + + } break; + case Image::FORMAT_RH: { + ERR_EXPLAIN("R half float texture not supported"); + ERR_FAIL_V(image); + } break; + case Image::FORMAT_RGH: { + ERR_EXPLAIN("RG half float texture not supported"); + ERR_FAIL_V(image); + + } break; + case Image::FORMAT_RGBH: { + ERR_EXPLAIN("RGB half float texture not supported"); + ERR_FAIL_V(image); + + } break; + case Image::FORMAT_RGBAH: { + ERR_EXPLAIN("RGBA half float texture not supported"); + ERR_FAIL_V(image); + + } break; + case Image::FORMAT_RGBE9995: { + ERR_EXPLAIN("RGBA float texture not supported"); + ERR_FAIL_V(image); + + } break; + case Image::FORMAT_DXT1: { + + need_decompress = true; + + } break; + case Image::FORMAT_DXT3: { + + need_decompress = true; + + } break; + case Image::FORMAT_DXT5: { + + need_decompress = true; + + } break; + case Image::FORMAT_RGTC_R: { + + need_decompress = true; + + } break; + case Image::FORMAT_RGTC_RG: { + + need_decompress = true; + + } break; + case Image::FORMAT_BPTC_RGBA: { + + need_decompress = true; + } break; + case Image::FORMAT_BPTC_RGBF: { + + need_decompress = true; + } break; + case Image::FORMAT_BPTC_RGBFU: { + + need_decompress = true; + } break; + case Image::FORMAT_PVRTC2: { + + need_decompress = true; + } break; + case Image::FORMAT_PVRTC2A: { + + need_decompress = true; + } break; + case Image::FORMAT_PVRTC4: { + + need_decompress = true; + } break; + case Image::FORMAT_PVRTC4A: { + + need_decompress = true; + } break; + case Image::FORMAT_ETC: { + + need_decompress = true; + } break; + case Image::FORMAT_ETC2_R11: { + + need_decompress = true; + } break; + case Image::FORMAT_ETC2_R11S: { + + need_decompress = true; + } break; + case Image::FORMAT_ETC2_RG11: { + + need_decompress = true; + } break; + case Image::FORMAT_ETC2_RG11S: { + + need_decompress = true; + } break; + case Image::FORMAT_ETC2_RGB8: { + + need_decompress = true; + } break; + case Image::FORMAT_ETC2_RGBA8: { + + need_decompress = true; + } break; + case Image::FORMAT_ETC2_RGB8A1: { + + need_decompress = true; + } break; + default: { + + ERR_FAIL_V(Ref<Image>()); + } + } + + if (need_decompress) { + + if (!image.is_null()) { + image = image->duplicate(); + image->decompress(); + ERR_FAIL_COND_V(image->is_compressed(), image); + image->convert(Image::FORMAT_RGBA8); + } + + r_gl_format = GL_RGBA; + r_gl_internal_format = GL_RGBA; + r_gl_type = GL_UNSIGNED_BYTE; + + return image; + } + + return p_image; +} + +static const GLenum _cube_side_enum[6] = { + + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + +}; + +RID RasterizerStorageGLES2::texture_create() { + + Texture *texture = memnew(Texture); + ERR_FAIL_COND_V(!texture, RID()); + glGenTextures(1, &texture->tex_id); + texture->active = false; + texture->total_data_size = 0; + + return texture_owner.make_rid(texture); +} + +void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags) { + GLenum format; + GLenum internal_format; + GLenum type; + + if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) { + p_flags &= ~VS::TEXTURE_FLAG_MIPMAPS; // no mipies for video + } + + Texture *texture = texture_owner.getornull(p_texture); + ERR_FAIL_COND(!texture); + texture->width = p_width; + texture->height = p_height; + texture->format = p_format; + texture->flags = p_flags; + texture->stored_cube_sides = 0; + texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; + + _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, format, internal_format, type); + + texture->alloc_width = texture->width; + texture->alloc_height = texture->height; + + texture->gl_format_cache = format; + texture->gl_type_cache = type; + texture->gl_internal_format_cache = internal_format; + texture->data_size = 0; + texture->mipmaps = 1; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(texture->target, texture->tex_id); + + if (p_flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) { + //prealloc if video + glTexImage2D(texture->target, 0, internal_format, p_width, p_height, 0, format, type, NULL); + } + + texture->active = true; +} + +void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side) { + Texture *texture = texture_owner.getornull(p_texture); + + ERR_FAIL_COND(!texture); + ERR_FAIL_COND(!texture->active); + ERR_FAIL_COND(texture->render_target); + ERR_FAIL_COND(texture->format != p_image->get_format()); + ERR_FAIL_COND(p_image.is_null()); + + GLenum type; + GLenum format; + GLenum internal_format; + bool compressed = false; + bool srgb; + + if (config.keep_original_textures && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) { + texture->images[p_cube_side] = p_image; + } + + Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, format, internal_format, type); + + if (config.shrink_textures_x2 && (p_image->has_mipmaps() || !p_image->is_compressed()) && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) { + + texture->alloc_height = MAX(1, texture->alloc_height / 2); + texture->alloc_width = MAX(1, texture->alloc_width / 2); + + if (texture->alloc_width == img->get_width() / 2 && texture->alloc_height == img->get_height() / 2) { + + img->shrink_x2(); + } else if (img->get_format() <= Image::FORMAT_RGBA8) { + + img->resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR); + } + }; + + GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_cube_side] : GL_TEXTURE_2D; + + texture->data_size = img->get_data().size(); + PoolVector<uint8_t>::Read read = img->get_data().read(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(texture->target, texture->tex_id); + + texture->ignore_mipmaps = compressed && !img->has_mipmaps(); + + if ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && !texture->ignore_mipmaps) + glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, config.use_fast_texture_filter ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR); + else { + if (texture->flags & VS::TEXTURE_FLAG_FILTER) { + glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + } + + if (texture->flags & VS::TEXTURE_FLAG_FILTER) { + + glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering + + } else { + + glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering + } + + if (((texture->flags & VS::TEXTURE_FLAG_REPEAT) || (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT)) && texture->target != GL_TEXTURE_CUBE_MAP) { + + if (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + } else { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + } else { + + //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); + glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + +//set swizle for older format compatibility +#ifdef GLES_OVER_GL + switch (texture->format) { + + case Image::FORMAT_L8: { + + } break; + case Image::FORMAT_LA8: { + + } break; + default: { + + } break; + } +#endif + + int mipmaps = ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && img->has_mipmaps()) ? img->get_mipmap_count() + 1 : 1; + + int w = img->get_width(); + int h = img->get_height(); + + int tsize = 0; + + for (int i = 0; i < mipmaps; i++) { + + int size, ofs; + img->get_mipmap_offset_and_size(i, ofs, size); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if (texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING) { + glTexSubImage2D(blit_target, i, 0, 0, w, h, format, type, &read[ofs]); + } else { + glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]); + } + + tsize += size; + + w = MAX(1, w >> 1); + h = MAX(1, h >> 1); + } + + info.texture_mem -= texture->total_data_size; + texture->total_data_size = tsize; + info.texture_mem += texture->total_data_size; + + // printf("texture: %i x %i - size: %i - total: %i\n", texture->width, texture->height, tsize, info.texture_mem); + + texture->stored_cube_sides |= (1 << p_cube_side); + + if ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && mipmaps == 1 && !texture->ignore_mipmaps && (!(texture->flags & VS::TEXTURE_FLAG_CUBEMAP) || texture->stored_cube_sides == (1 << 6) - 1)) { + //generate mipmaps if they were requested and the image does not contain them + glGenerateMipmap(texture->target); + } + + texture->mipmaps = mipmaps; +} + +Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side) const { + + Texture *texture = texture_owner.getornull(p_texture); + + ERR_FAIL_COND_V(!texture, Ref<Image>()); + ERR_FAIL_COND_V(!texture->active, Ref<Image>()); + ERR_FAIL_COND_V(texture->data_size == 0 && !texture->render_target, Ref<Image>()); + + if (!texture->images[p_cube_side].is_null()) { + return texture->images[p_cube_side]; + } +#ifdef GLES_OVER_GL + + PoolVector<uint8_t> data; + + int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->format, texture->mipmaps > 1 ? -1 : 0); + + data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers + PoolVector<uint8_t>::Write wb = data.write(); + + glActiveTexture(GL_TEXTURE0); + + glBindTexture(texture->target, texture->tex_id); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + + //print_line("GET FORMAT: " + Image::get_format_name(texture->format) + " mipmaps: " + itos(texture->mipmaps)); + + for (int i = 0; i < texture->mipmaps; i++) { + + int ofs = 0; + if (i > 0) { + ofs = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->format, i - 1); + } + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + glGetTexImage(texture->target, i, texture->gl_format_cache, texture->gl_type_cache, &wb[ofs]); + } + + wb = PoolVector<uint8_t>::Write(); + + data.resize(data_size); + + Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1 ? true : false, texture->format, data)); + + return Ref<Image>(img); +#else + + ERR_EXPLAIN("Sorry, It's not posible to obtain images back in OpenGL ES"); + return Ref<Image>(); +#endif +} + +void RasterizerStorageGLES2::texture_set_flags(RID p_texture, uint32_t p_flags) { + + Texture *texture = texture_owner.getornull(p_texture); + ERR_FAIL_COND(!texture); + + bool had_mipmaps = texture->flags & VS::TEXTURE_FLAG_MIPMAPS; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(texture->target, texture->tex_id); + uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP; + texture->flags = p_flags | cube; // can't remove a cube from being a cube + + if (((texture->flags & VS::TEXTURE_FLAG_REPEAT) || (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT)) && texture->target != GL_TEXTURE_CUBE_MAP) { + + if (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); + } else { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + } else { + //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); + glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + if ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && !texture->ignore_mipmaps) { + if (!had_mipmaps && texture->mipmaps == 1) { + glGenerateMipmap(texture->target); + } + glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, config.use_fast_texture_filter ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR); + + } else { + if (texture->flags & VS::TEXTURE_FLAG_FILTER) { + glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + } + + if (texture->flags & VS::TEXTURE_FLAG_FILTER) { + + glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering + + } else { + + glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering + } +} + +uint32_t RasterizerStorageGLES2::texture_get_flags(RID p_texture) const { + Texture *texture = texture_owner.getornull(p_texture); + + ERR_FAIL_COND_V(!texture, 0); + + return texture->flags; +} + +Image::Format RasterizerStorageGLES2::texture_get_format(RID p_texture) const { + Texture *texture = texture_owner.getornull(p_texture); + + ERR_FAIL_COND_V(!texture, Image::FORMAT_L8); + + return texture->format; +} + +uint32_t RasterizerStorageGLES2::texture_get_texid(RID p_texture) const { + Texture *texture = texture_owner.getornull(p_texture); + + ERR_FAIL_COND_V(!texture, 0); + + return texture->tex_id; +} + +uint32_t RasterizerStorageGLES2::texture_get_width(RID p_texture) const { + Texture *texture = texture_owner.getornull(p_texture); + + ERR_FAIL_COND_V(!texture, 0); + + return texture->width; +} + +uint32_t RasterizerStorageGLES2::texture_get_height(RID p_texture) const { + Texture *texture = texture_owner.getornull(p_texture); + + ERR_FAIL_COND_V(!texture, 0); + + return texture->height; +} + +void RasterizerStorageGLES2::texture_set_size_override(RID p_texture, int p_width, int p_height) { + Texture *texture = texture_owner.getornull(p_texture); + + ERR_FAIL_COND(!texture); + ERR_FAIL_COND(texture->render_target); + + ERR_FAIL_COND(p_width <= 0 || p_width > 16384); + ERR_FAIL_COND(p_height <= 0 || p_height > 16384); + //real texture size is in alloc width and height + texture->width = p_width; + texture->height = p_height; +} + +void RasterizerStorageGLES2::texture_set_path(RID p_texture, const String &p_path) { + Texture *texture = texture_owner.getornull(p_texture); + ERR_FAIL_COND(!texture); + + texture->path = p_path; +} + +String RasterizerStorageGLES2::texture_get_path(RID p_texture) const { + Texture *texture = texture_owner.getornull(p_texture); + ERR_FAIL_COND_V(!texture, ""); + + return texture->path; +} + +void RasterizerStorageGLES2::texture_debug_usage(List<VS::TextureInfo> *r_info) { + List<RID> textures; + texture_owner.get_owned_list(&textures); + + for (List<RID>::Element *E = textures.front(); E; E = E->next()) { + + Texture *t = texture_owner.getornull(E->get()); + if (!t) + continue; + VS::TextureInfo tinfo; + tinfo.path = t->path; + tinfo.format = t->format; + tinfo.size.x = t->alloc_width; + tinfo.size.y = t->alloc_height; + tinfo.bytes = t->total_data_size; + r_info->push_back(tinfo); + } +} + +void RasterizerStorageGLES2::texture_set_shrink_all_x2_on_set_data(bool p_enable) { + config.shrink_textures_x2 = p_enable; +} + +void RasterizerStorageGLES2::textures_keep_original(bool p_enable) { + config.keep_original_textures = p_enable; +} + +void RasterizerStorageGLES2::texture_set_proxy(RID p_texture, RID p_proxy) { + Texture *texture = texture_owner.getornull(p_texture); + ERR_FAIL_COND(!texture); + + if (texture->proxy) { + texture->proxy->proxy_owners.erase(texture); + texture->proxy = NULL; + } + + if (p_proxy.is_valid()) { + Texture *proxy = texture_owner.get(p_proxy); + ERR_FAIL_COND(!proxy); + ERR_FAIL_COND(proxy == texture); + proxy->proxy_owners.insert(texture); + texture->proxy = proxy; + } +} + +void RasterizerStorageGLES2::texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) { + // TODO +} + +void RasterizerStorageGLES2::texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) { + // TODO +} + +void RasterizerStorageGLES2::texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) { + // TODO +} + +RID RasterizerStorageGLES2::texture_create_radiance_cubemap(RID p_source, int p_resolution) const { + // TODO + return RID(); +} + +RID RasterizerStorageGLES2::sky_create() { + return RID(); +} + +void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size) { +} + +/* SHADER API */ + +RID RasterizerStorageGLES2::shader_create() { + + Shader *shader = memnew(Shader); + shader->mode = VS::SHADER_SPATIAL; + shader->shader = &scene->state.scene_shader; + RID rid = shader_owner.make_rid(shader); + _shader_make_dirty(shader); + shader->self = rid; + + return rid; +} + +void RasterizerStorageGLES2::_shader_make_dirty(Shader *p_shader) { + if (p_shader->dirty_list.in_list()) + return; + + _shader_dirty_list.add(&p_shader->dirty_list); +} + +void RasterizerStorageGLES2::shader_set_code(RID p_shader, const String &p_code) { + + Shader *shader = shader_owner.getornull(p_shader); + ERR_FAIL_COND(!shader); + + shader->code = p_code; + + String mode_string = ShaderLanguage::get_shader_type(p_code); + VS::ShaderMode mode; + + if (mode_string == "canvas_item") + mode = VS::SHADER_CANVAS_ITEM; + else if (mode_string == "particles") + mode = VS::SHADER_PARTICLES; + else + mode = VS::SHADER_SPATIAL; + + if (shader->custom_code_id && mode != shader->mode) { + shader->shader->free_custom_shader(shader->custom_code_id); + shader->custom_code_id = 0; + } + + shader->mode = mode; + + // TODO handle all shader types + if (mode == VS::SHADER_CANVAS_ITEM) { + shader->shader = &canvas->state.canvas_shader; + + } else { + return; + } + + if (shader->custom_code_id == 0) { + shader->custom_code_id = shader->shader->create_custom_shader(); + } + + _shader_make_dirty(shader); +} + +String RasterizerStorageGLES2::shader_get_code(RID p_shader) const { + + const Shader *shader = shader_owner.get(p_shader); + ERR_FAIL_COND_V(!shader, ""); + + return shader->code; +} + +void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const { + + _shader_dirty_list.remove(&p_shader->dirty_list); + + p_shader->valid = false; + + p_shader->uniforms.clear(); + + ShaderCompilerGLES2::GeneratedCode gen_code; + ShaderCompilerGLES2::IdentifierActions *actions = NULL; + + switch (p_shader->mode) { + + // TODO + + case VS::SHADER_CANVAS_ITEM: { + + p_shader->canvas_item.blend_mode = Shader::CanvasItem::BLEND_MODE_MIX; + + p_shader->canvas_item.uses_screen_texture = false; + p_shader->canvas_item.uses_screen_uv = false; + p_shader->canvas_item.uses_time = false; + + shaders.actions_canvas.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_ADD); + shaders.actions_canvas.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX); + shaders.actions_canvas.render_mode_values["blend_sub"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_SUB); + shaders.actions_canvas.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MUL); + shaders.actions_canvas.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_PMALPHA); + + // shaders.actions_canvas.render_mode_values["unshaded"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_UNSHADED); + // shaders.actions_canvas.render_mode_values["light_only"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY); + + shaders.actions_canvas.usage_flag_pointers["SCREEN_UV"] = &p_shader->canvas_item.uses_screen_uv; + shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv; + shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture; + shaders.actions_canvas.usage_flag_pointers["TIME"] = &p_shader->canvas_item.uses_time; + + actions = &shaders.actions_canvas; + actions->uniforms = &p_shader->uniforms; + } break; + + default: { + return; + } break; + } + + Error err = shaders.compiler.compile(p_shader->mode, p_shader->code, actions, p_shader->path, gen_code); + + ERR_FAIL_COND(err != OK); + + p_shader->shader->set_custom_shader_code(p_shader->custom_code_id, gen_code.vertex, gen_code.vertex_global, gen_code.fragment, gen_code.light, gen_code.fragment_global, gen_code.uniforms, gen_code.texture_uniforms, gen_code.custom_defines); + + p_shader->texture_count = gen_code.texture_uniforms.size(); + p_shader->texture_hints = gen_code.texture_hints; + + p_shader->uses_vertex_time = gen_code.uses_vertex_time; + p_shader->uses_fragment_time = gen_code.uses_fragment_time; + + for (SelfList<Material> *E = p_shader->materials.first(); E; E = E->next()) { + _material_make_dirty(E->self()); + } + + p_shader->valid = true; + p_shader->version++; +} + +void RasterizerStorageGLES2::update_dirty_shaders() { + while (_shader_dirty_list.first()) { + _update_shader(_shader_dirty_list.first()->self()); + } +} + +void RasterizerStorageGLES2::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { + + Shader *shader = shader_owner.get(p_shader); + ERR_FAIL_COND(!shader); + + if (shader->dirty_list.in_list()) { + _update_shader(shader); + } + + Map<int, StringName> order; + + for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) { + + if (E->get().texture_order >= 0) { + order[E->get().texture_order + 100000] = E->key(); + } else { + order[E->get().order] = E->key(); + } + } + + for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { + + PropertyInfo pi; + ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[E->get()]; + + pi.name = E->get(); + + switch (u.type) { + case ShaderLanguage::TYPE_VOID: { + pi.type = Variant::NIL; + } break; + + case ShaderLanguage::TYPE_BOOL: { + pi.type = Variant::BOOL; + } break; + + // bool vectors + case ShaderLanguage::TYPE_BVEC2: { + pi.type = Variant::INT; + pi.hint = PROPERTY_HINT_FLAGS; + pi.hint_string = "x,y"; + } break; + case ShaderLanguage::TYPE_BVEC3: { + pi.type = Variant::INT; + pi.hint = PROPERTY_HINT_FLAGS; + pi.hint_string = "x,y,z"; + } break; + case ShaderLanguage::TYPE_BVEC4: { + pi.type = Variant::INT; + pi.hint = PROPERTY_HINT_FLAGS; + pi.hint_string = "x,y,z,w"; + } break; + + // int stuff + case ShaderLanguage::TYPE_UINT: + case ShaderLanguage::TYPE_INT: { + pi.type = Variant::INT; + + if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) { + pi.hint = PROPERTY_HINT_RANGE; + pi.hint_string = rtos(u.hint_range[0]) + "," + rtos(u.hint_range[1]); + } + } break; + + case ShaderLanguage::TYPE_IVEC2: + case ShaderLanguage::TYPE_UVEC2: + case ShaderLanguage::TYPE_IVEC3: + case ShaderLanguage::TYPE_UVEC3: + case ShaderLanguage::TYPE_IVEC4: + case ShaderLanguage::TYPE_UVEC4: { + pi.type = Variant::POOL_INT_ARRAY; + } break; + + case ShaderLanguage::TYPE_VEC2: { + pi.type = Variant::VECTOR2; + } break; + case ShaderLanguage::TYPE_VEC3: { + pi.type = Variant::VECTOR3; + } break; + + case ShaderLanguage::TYPE_VEC4: { + if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { + pi.type = Variant::COLOR; + } else { + pi.type = Variant::PLANE; + } + } break; + + case ShaderLanguage::TYPE_MAT2: { + pi.type = Variant::TRANSFORM2D; + } break; + + case ShaderLanguage::TYPE_MAT3: { + pi.type = Variant::BASIS; + } break; + + case ShaderLanguage::TYPE_MAT4: { + pi.type = Variant::TRANSFORM; + } break; + + case ShaderLanguage::TYPE_SAMPLER2D: + case ShaderLanguage::TYPE_ISAMPLER2D: + case ShaderLanguage::TYPE_USAMPLER2D: { + pi.type = Variant::OBJECT; + pi.hint = PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string = "Texture"; + } break; + + case ShaderLanguage::TYPE_SAMPLERCUBE: { + pi.type = Variant::OBJECT; + pi.hint = PROPERTY_HINT_RESOURCE_TYPE; + pi.hint_string = "CubeMap"; + } break; + } + + p_param_list->push_back(pi); + } +} + +void RasterizerStorageGLES2::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) { + + Shader *shader = shader_owner.get(p_shader); + ERR_FAIL_COND(!shader); + ERR_FAIL_COND(p_texture.is_valid() && !texture_owner.owns(p_texture)); + + if (p_texture.is_valid()) { + shader->default_textures[p_name] = p_texture; + } else { + shader->default_textures.erase(p_name); + } + + _shader_make_dirty(shader); +} + +RID RasterizerStorageGLES2::shader_get_default_texture_param(RID p_shader, const StringName &p_name) const { + + const Shader *shader = shader_owner.get(p_shader); + ERR_FAIL_COND_V(!shader, RID()); + + const Map<StringName, RID>::Element *E = shader->default_textures.find(p_name); + + if (!E) { + return RID(); + } + + return E->get(); +} + +/* COMMON MATERIAL API */ + +void RasterizerStorageGLES2::_material_make_dirty(Material *p_material) const { + + if (p_material->dirty_list.in_list()) + return; + + _material_dirty_list.add(&p_material->dirty_list); +} + +RID RasterizerStorageGLES2::material_create() { + + Material *material = memnew(Material); + + return material_owner.make_rid(material); +} + +void RasterizerStorageGLES2::material_set_shader(RID p_material, RID p_shader) { + + Material *material = material_owner.get(p_material); + ERR_FAIL_COND(!material); + + Shader *shader = shader_owner.getornull(p_shader); + + if (material->shader) { + // if a shader is present, remove the old shader + material->shader->materials.remove(&material->list); + } + + material->shader = shader; + + if (shader) { + shader->materials.add(&material->list); + } + + _material_make_dirty(material); +} + +RID RasterizerStorageGLES2::material_get_shader(RID p_material) const { + + const Material *material = material_owner.get(p_material); + ERR_FAIL_COND_V(!material, RID()); + + if (material->shader) { + return material->shader->self; + } + + return RID(); +} + +void RasterizerStorageGLES2::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) { + + Material *material = material_owner.get(p_material); + ERR_FAIL_COND(!material); + + if (p_value.get_type() == Variant::NIL) { + material->params.erase(p_param); + } else { + material->params[p_param] = p_value; + } + + _material_make_dirty(material); +} + +Variant RasterizerStorageGLES2::material_get_param(RID p_material, const StringName &p_param) const { + + const Material *material = material_owner.get(p_material); + ERR_FAIL_COND_V(!material, RID()); + + if (material->params.has(p_param)) { + return material->params[p_param]; + } + + return Variant(); +} + +void RasterizerStorageGLES2::material_set_line_width(RID p_material, float p_width) { +} + +void RasterizerStorageGLES2::material_set_next_pass(RID p_material, RID p_next_material) { +} + +bool RasterizerStorageGLES2::material_is_animated(RID p_material) { + return false; +} + +bool RasterizerStorageGLES2::material_casts_shadows(RID p_material) { + return false; +} + +void RasterizerStorageGLES2::material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance) { +} + +void RasterizerStorageGLES2::material_remove_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance) { +} + +void RasterizerStorageGLES2::material_set_render_priority(RID p_material, int priority) { +} + +void RasterizerStorageGLES2::update_dirty_materials() { +} + +/* MESH API */ + +RID RasterizerStorageGLES2::mesh_create() { + return RID(); +} + +void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabbs) { +} + +void RasterizerStorageGLES2::mesh_set_blend_shape_count(RID p_mesh, int p_amount) { +} + +int RasterizerStorageGLES2::mesh_get_blend_shape_count(RID p_mesh) const { + return 0; +} + +void RasterizerStorageGLES2::mesh_set_blend_shape_mode(RID p_mesh, VS::BlendShapeMode p_mode) { +} + +VS::BlendShapeMode RasterizerStorageGLES2::mesh_get_blend_shape_mode(RID p_mesh) const { + return VS::BLEND_SHAPE_MODE_NORMALIZED; +} + +void RasterizerStorageGLES2::mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector<uint8_t> &p_data) { +} + +void RasterizerStorageGLES2::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) { +} + +RID RasterizerStorageGLES2::mesh_surface_get_material(RID p_mesh, int p_surface) const { + return RID(); +} + +int RasterizerStorageGLES2::mesh_surface_get_array_len(RID p_mesh, int p_surface) const { + return 0; +} + +int RasterizerStorageGLES2::mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const { + return 0; +} + +PoolVector<uint8_t> RasterizerStorageGLES2::mesh_surface_get_array(RID p_mesh, int p_surface) const { + return PoolVector<uint8_t>(); +} + +PoolVector<uint8_t> RasterizerStorageGLES2::mesh_surface_get_index_array(RID p_mesh, int p_surface) const { + return PoolVector<uint8_t>(); +} + +uint32_t RasterizerStorageGLES2::mesh_surface_get_format(RID p_mesh, int p_surface) const { + return 0; +} + +VS::PrimitiveType RasterizerStorageGLES2::mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const { + return VS::PRIMITIVE_TRIANGLES; +} + +AABB RasterizerStorageGLES2::mesh_surface_get_aabb(RID p_mesh, int p_surface) const { + return AABB(); +} + +Vector<PoolVector<uint8_t> > RasterizerStorageGLES2::mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const { + return Vector<PoolVector<uint8_t> >(); +} +Vector<AABB> RasterizerStorageGLES2::mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const { + return Vector<AABB>(); +} + +void RasterizerStorageGLES2::mesh_remove_surface(RID p_mesh, int p_surface) { +} + +int RasterizerStorageGLES2::mesh_get_surface_count(RID p_mesh) const { + return 0; +} + +void RasterizerStorageGLES2::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { +} + +AABB RasterizerStorageGLES2::mesh_get_custom_aabb(RID p_mesh) const { + return AABB(); +} + +AABB RasterizerStorageGLES2::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { + return AABB(); +} +void RasterizerStorageGLES2::mesh_clear(RID p_mesh) { +} + +/* MULTIMESH API */ + +RID RasterizerStorageGLES2::multimesh_create() { + return RID(); +} + +void RasterizerStorageGLES2::multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format) { +} + +int RasterizerStorageGLES2::multimesh_get_instance_count(RID p_multimesh) const { + return 0; +} + +void RasterizerStorageGLES2::multimesh_set_mesh(RID p_multimesh, RID p_mesh) { +} + +void RasterizerStorageGLES2::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) { +} + +void RasterizerStorageGLES2::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) { +} + +void RasterizerStorageGLES2::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { +} + +RID RasterizerStorageGLES2::multimesh_get_mesh(RID p_multimesh) const { + return RID(); +} + +Transform RasterizerStorageGLES2::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { + return Transform(); +} + +Transform2D RasterizerStorageGLES2::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { + return Transform2D(); +} + +Color RasterizerStorageGLES2::multimesh_instance_get_color(RID p_multimesh, int p_index) const { + return Color(); +} + +void RasterizerStorageGLES2::multimesh_set_visible_instances(RID p_multimesh, int p_visible) { +} + +int RasterizerStorageGLES2::multimesh_get_visible_instances(RID p_multimesh) const { + return 0; +} + +AABB RasterizerStorageGLES2::multimesh_get_aabb(RID p_multimesh) const { + + return AABB(); +} + +void RasterizerStorageGLES2::update_dirty_multimeshes() { +} + +/* IMMEDIATE API */ + +RID RasterizerStorageGLES2::immediate_create() { + return RID(); +} + +void RasterizerStorageGLES2::immediate_begin(RID p_immediate, VS::PrimitiveType p_rimitive, RID p_texture) { +} + +void RasterizerStorageGLES2::immediate_vertex(RID p_immediate, const Vector3 &p_vertex) { +} + +void RasterizerStorageGLES2::immediate_normal(RID p_immediate, const Vector3 &p_normal) { +} + +void RasterizerStorageGLES2::immediate_tangent(RID p_immediate, const Plane &p_tangent) { +} + +void RasterizerStorageGLES2::immediate_color(RID p_immediate, const Color &p_color) { +} + +void RasterizerStorageGLES2::immediate_uv(RID p_immediate, const Vector2 &tex_uv) { +} + +void RasterizerStorageGLES2::immediate_uv2(RID p_immediate, const Vector2 &tex_uv) { +} + +void RasterizerStorageGLES2::immediate_end(RID p_immediate) { +} + +void RasterizerStorageGLES2::immediate_clear(RID p_immediate) { +} + +AABB RasterizerStorageGLES2::immediate_get_aabb(RID p_immediate) const { + return AABB(); +} + +void RasterizerStorageGLES2::immediate_set_material(RID p_immediate, RID p_material) { +} + +RID RasterizerStorageGLES2::immediate_get_material(RID p_immediate) const { + return RID(); +} + +/* SKELETON API */ + +RID RasterizerStorageGLES2::skeleton_create() { + return RID(); +} + +void RasterizerStorageGLES2::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) { +} + +int RasterizerStorageGLES2::skeleton_get_bone_count(RID p_skeleton) const { + return 0; +} + +void RasterizerStorageGLES2::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) { +} + +Transform RasterizerStorageGLES2::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { + return Transform(); +} +void RasterizerStorageGLES2::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { +} + +Transform2D RasterizerStorageGLES2::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { + return Transform2D(); +} + +void RasterizerStorageGLES2::update_dirty_skeletons() { +} + +/* Light API */ + +RID RasterizerStorageGLES2::light_create(VS::LightType p_type) { + return RID(); +} + +void RasterizerStorageGLES2::light_set_color(RID p_light, const Color &p_color) { +} + +void RasterizerStorageGLES2::light_set_param(RID p_light, VS::LightParam p_param, float p_value) { +} + +void RasterizerStorageGLES2::light_set_shadow(RID p_light, bool p_enabled) { +} + +void RasterizerStorageGLES2::light_set_shadow_color(RID p_light, const Color &p_color) { +} + +void RasterizerStorageGLES2::light_set_projector(RID p_light, RID p_texture) { +} + +void RasterizerStorageGLES2::light_set_negative(RID p_light, bool p_enable) { +} + +void RasterizerStorageGLES2::light_set_cull_mask(RID p_light, uint32_t p_mask) { +} + +void RasterizerStorageGLES2::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { +} + +void RasterizerStorageGLES2::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) { +} + +VS::LightOmniShadowMode RasterizerStorageGLES2::light_omni_get_shadow_mode(RID p_light) { + return VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; +} + +void RasterizerStorageGLES2::light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail) { +} + +void RasterizerStorageGLES2::light_directional_set_shadow_mode(RID p_light, VS::LightDirectionalShadowMode p_mode) { +} + +void RasterizerStorageGLES2::light_directional_set_blend_splits(RID p_light, bool p_enable) { +} + +bool RasterizerStorageGLES2::light_directional_get_blend_splits(RID p_light) const { + return false; +} + +VS::LightDirectionalShadowMode RasterizerStorageGLES2::light_directional_get_shadow_mode(RID p_light) { + return VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; +} + +void RasterizerStorageGLES2::light_directional_set_shadow_depth_range_mode(RID p_light, VS::LightDirectionalShadowDepthRangeMode p_range_mode) { +} + +VS::LightDirectionalShadowDepthRangeMode RasterizerStorageGLES2::light_directional_get_shadow_depth_range_mode(RID p_light) const { + return VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE; +} + +VS::LightType RasterizerStorageGLES2::light_get_type(RID p_light) const { + return VS::LIGHT_DIRECTIONAL; +} + +float RasterizerStorageGLES2::light_get_param(RID p_light, VS::LightParam p_param) { + + return VS::LIGHT_DIRECTIONAL; +} + +Color RasterizerStorageGLES2::light_get_color(RID p_light) { + return Color(); +} + +bool RasterizerStorageGLES2::light_has_shadow(RID p_light) const { + + return VS::LIGHT_DIRECTIONAL; +} + +uint64_t RasterizerStorageGLES2::light_get_version(RID p_light) const { + return 0; +} + +AABB RasterizerStorageGLES2::light_get_aabb(RID p_light) const { + return AABB(); +} + +/* PROBE API */ + +RID RasterizerStorageGLES2::reflection_probe_create() { + return RID(); +} + +void RasterizerStorageGLES2::reflection_probe_set_update_mode(RID p_probe, VS::ReflectionProbeUpdateMode p_mode) { +} + +void RasterizerStorageGLES2::reflection_probe_set_intensity(RID p_probe, float p_intensity) { +} + +void RasterizerStorageGLES2::reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient) { +} + +void RasterizerStorageGLES2::reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy) { +} + +void RasterizerStorageGLES2::reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib) { +} + +void RasterizerStorageGLES2::reflection_probe_set_max_distance(RID p_probe, float p_distance) { +} + +void RasterizerStorageGLES2::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { +} + +void RasterizerStorageGLES2::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { +} + +void RasterizerStorageGLES2::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { +} + +void RasterizerStorageGLES2::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { +} + +void RasterizerStorageGLES2::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) { +} + +void RasterizerStorageGLES2::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { +} + +AABB RasterizerStorageGLES2::reflection_probe_get_aabb(RID p_probe) const { + return AABB(); +} +VS::ReflectionProbeUpdateMode RasterizerStorageGLES2::reflection_probe_get_update_mode(RID p_probe) const { + return VS::REFLECTION_PROBE_UPDATE_ALWAYS; +} + +uint32_t RasterizerStorageGLES2::reflection_probe_get_cull_mask(RID p_probe) const { + return 0; +} + +Vector3 RasterizerStorageGLES2::reflection_probe_get_extents(RID p_probe) const { + return Vector3(); +} +Vector3 RasterizerStorageGLES2::reflection_probe_get_origin_offset(RID p_probe) const { + return Vector3(); +} + +bool RasterizerStorageGLES2::reflection_probe_renders_shadows(RID p_probe) const { + return false; +} + +float RasterizerStorageGLES2::reflection_probe_get_origin_max_distance(RID p_probe) const { + return 0; +} + +RID RasterizerStorageGLES2::gi_probe_create() { + return RID(); +} + +void RasterizerStorageGLES2::gi_probe_set_bounds(RID p_probe, const AABB &p_bounds) { +} + +AABB RasterizerStorageGLES2::gi_probe_get_bounds(RID p_probe) const { + return AABB(); +} + +void RasterizerStorageGLES2::gi_probe_set_cell_size(RID p_probe, float p_size) { +} + +float RasterizerStorageGLES2::gi_probe_get_cell_size(RID p_probe) const { + return 0.0; +} + +void RasterizerStorageGLES2::gi_probe_set_to_cell_xform(RID p_probe, const Transform &p_xform) { +} + +Transform RasterizerStorageGLES2::gi_probe_get_to_cell_xform(RID p_probe) const { + return Transform(); +} + +void RasterizerStorageGLES2::gi_probe_set_dynamic_data(RID p_probe, const PoolVector<int> &p_data) { +} + +PoolVector<int> RasterizerStorageGLES2::gi_probe_get_dynamic_data(RID p_probe) const { + return PoolVector<int>(); +} + +void RasterizerStorageGLES2::gi_probe_set_dynamic_range(RID p_probe, int p_range) { +} + +int RasterizerStorageGLES2::gi_probe_get_dynamic_range(RID p_probe) const { + return 0; +} + +void RasterizerStorageGLES2::gi_probe_set_energy(RID p_probe, float p_range) { +} + +void RasterizerStorageGLES2::gi_probe_set_bias(RID p_probe, float p_range) { +} + +void RasterizerStorageGLES2::gi_probe_set_normal_bias(RID p_probe, float p_range) { +} + +void RasterizerStorageGLES2::gi_probe_set_propagation(RID p_probe, float p_range) { +} + +void RasterizerStorageGLES2::gi_probe_set_interior(RID p_probe, bool p_enable) { +} + +bool RasterizerStorageGLES2::gi_probe_is_interior(RID p_probe) const { + return false; +} + +void RasterizerStorageGLES2::gi_probe_set_compress(RID p_probe, bool p_enable) { +} + +bool RasterizerStorageGLES2::gi_probe_is_compressed(RID p_probe) const { + return false; +} +float RasterizerStorageGLES2::gi_probe_get_energy(RID p_probe) const { + return 0; +} + +float RasterizerStorageGLES2::gi_probe_get_bias(RID p_probe) const { + return 0; +} + +float RasterizerStorageGLES2::gi_probe_get_normal_bias(RID p_probe) const { + return 0; +} + +float RasterizerStorageGLES2::gi_probe_get_propagation(RID p_probe) const { + return 0; +} + +uint32_t RasterizerStorageGLES2::gi_probe_get_version(RID p_probe) { + return 0; +} + +RasterizerStorage::GIProbeCompression RasterizerStorageGLES2::gi_probe_get_dynamic_data_get_preferred_compression() const { + return GI_PROBE_UNCOMPRESSED; +} + +RID RasterizerStorageGLES2::gi_probe_dynamic_data_create(int p_width, int p_height, int p_depth, GIProbeCompression p_compression) { + return RID(); +} + +void RasterizerStorageGLES2::gi_probe_dynamic_data_update(RID p_gi_probe_data, int p_depth_slice, int p_slice_count, int p_mipmap, const void *p_data) { +} + +/////// + +RID RasterizerStorageGLES2::lightmap_capture_create() { + return RID(); +} + +void RasterizerStorageGLES2::lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) { +} + +AABB RasterizerStorageGLES2::lightmap_capture_get_bounds(RID p_capture) const { + return AABB(); +} + +void RasterizerStorageGLES2::lightmap_capture_set_octree(RID p_capture, const PoolVector<uint8_t> &p_octree) { +} + +PoolVector<uint8_t> RasterizerStorageGLES2::lightmap_capture_get_octree(RID p_capture) const { + return PoolVector<uint8_t>(); +} + +void RasterizerStorageGLES2::lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) { +} + +Transform RasterizerStorageGLES2::lightmap_capture_get_octree_cell_transform(RID p_capture) const { + return Transform(); +} + +void RasterizerStorageGLES2::lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) { +} + +int RasterizerStorageGLES2::lightmap_capture_get_octree_cell_subdiv(RID p_capture) const { + return 0; +} + +void RasterizerStorageGLES2::lightmap_capture_set_energy(RID p_capture, float p_energy) { +} + +float RasterizerStorageGLES2::lightmap_capture_get_energy(RID p_capture) const { + return 0.0; +} + +const PoolVector<RasterizerStorage::LightmapCaptureOctree> *RasterizerStorageGLES2::lightmap_capture_get_octree_ptr(RID p_capture) const { + return NULL; +} + +/////// + +RID RasterizerStorageGLES2::particles_create() { + return RID(); +} + +void RasterizerStorageGLES2::particles_set_emitting(RID p_particles, bool p_emitting) { +} + +bool RasterizerStorageGLES2::particles_get_emitting(RID p_particles) { + return false; +} + +void RasterizerStorageGLES2::particles_set_amount(RID p_particles, int p_amount) { +} + +void RasterizerStorageGLES2::particles_set_lifetime(RID p_particles, float p_lifetime) { +} + +void RasterizerStorageGLES2::particles_set_one_shot(RID p_particles, bool p_one_shot) { +} + +void RasterizerStorageGLES2::particles_set_pre_process_time(RID p_particles, float p_time) { +} + +void RasterizerStorageGLES2::particles_set_explosiveness_ratio(RID p_particles, float p_ratio) { +} + +void RasterizerStorageGLES2::particles_set_randomness_ratio(RID p_particles, float p_ratio) { +} + +void RasterizerStorageGLES2::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) { +} + +void RasterizerStorageGLES2::particles_set_speed_scale(RID p_particles, float p_scale) { +} + +void RasterizerStorageGLES2::particles_set_use_local_coordinates(RID p_particles, bool p_enable) { +} + +void RasterizerStorageGLES2::particles_set_fixed_fps(RID p_particles, int p_fps) { +} + +void RasterizerStorageGLES2::particles_set_fractional_delta(RID p_particles, bool p_enable) { +} + +void RasterizerStorageGLES2::particles_set_process_material(RID p_particles, RID p_material) { +} + +void RasterizerStorageGLES2::particles_set_draw_order(RID p_particles, VS::ParticlesDrawOrder p_order) { +} + +void RasterizerStorageGLES2::particles_set_draw_passes(RID p_particles, int p_passes) { +} + +void RasterizerStorageGLES2::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) { +} + +void RasterizerStorageGLES2::particles_restart(RID p_particles) { +} + +void RasterizerStorageGLES2::particles_request_process(RID p_particles) { +} + +AABB RasterizerStorageGLES2::particles_get_current_aabb(RID p_particles) { + return AABB(); +} + +AABB RasterizerStorageGLES2::particles_get_aabb(RID p_particles) const { + return AABB(); +} + +void RasterizerStorageGLES2::particles_set_emission_transform(RID p_particles, const Transform &p_transform) { +} + +int RasterizerStorageGLES2::particles_get_draw_passes(RID p_particles) const { + return 0; +} + +RID RasterizerStorageGLES2::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { + return RID(); +} + +void RasterizerStorageGLES2::update_particles() { +} + +//////// + +void RasterizerStorageGLES2::instance_add_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) { +} + +void RasterizerStorageGLES2::instance_remove_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) { +} + +void RasterizerStorageGLES2::instance_add_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) { +} + +void RasterizerStorageGLES2::instance_remove_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) { +} + +/* RENDER TARGET */ + +void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { + + if (rt->width <= 0 || rt->height <= 0) + return; + + Texture *texture = texture_owner.getornull(rt->texture); + ERR_FAIL_COND(!texture); + + // create fbo + + glGenFramebuffers(1, &rt->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo); + + // color + + glGenTextures(1, &rt->color); + glBindTexture(GL_TEXTURE_2D, rt->color); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + if (texture->flags & VS::TEXTURE_FLAG_FILTER) { + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); + + // depth + + glGenRenderbuffers(1, &rt->depth); + glBindRenderbuffer(GL_RENDERBUFFER, rt->depth); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, rt->width, rt->height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + + glDeleteRenderbuffers(1, &rt->fbo); + glDeleteTextures(1, &rt->depth); + glDeleteTextures(1, &rt->color); + rt->fbo = 0; + rt->width = 0; + rt->height = 0; + rt->color = 0; + rt->depth = 0; + texture->tex_id = 0; + texture->active = false; + WARN_PRINT("Could not create framebuffer!!"); + return; + } + + texture->format = Image::FORMAT_RGBA8; + texture->gl_format_cache = GL_RGBA; + texture->gl_type_cache = GL_UNSIGNED_BYTE; + texture->gl_internal_format_cache = GL_RGBA; + texture->tex_id = rt->color; + texture->width = rt->width; + texture->alloc_width = rt->width; + texture->height = rt->height; + texture->alloc_height = rt->height; + texture->active = true; + + texture_set_flags(rt->texture, texture->flags); + + // copy texscreen buffers + { + int w = rt->width; + int h = rt->height; + + glGenTextures(1, &rt->copy_screen_effect.color); + glBindTexture(GL_TEXTURE_2D, rt->copy_screen_effect.color); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + glGenFramebuffers(1, &rt->copy_screen_effect.fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->copy_screen_effect.fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + _render_target_clear(rt); + ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); + } + } + + glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo); +} + +void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) { + + if (rt->fbo) { + glDeleteFramebuffers(1, &rt->fbo); + glDeleteTextures(1, &rt->color); + rt->fbo = 0; + } + + if (rt->depth) { + glDeleteRenderbuffers(1, &rt->depth); + rt->depth = 0; + } + + Texture *tex = texture_owner.get(rt->texture); + tex->alloc_height = 0; + tex->alloc_width = 0; + tex->width = 0; + tex->height = 0; + tex->active = false; + + // TODO hardcoded texscreen copy effect + if (rt->copy_screen_effect.color) { + glDeleteFramebuffers(1, &rt->copy_screen_effect.fbo); + rt->copy_screen_effect.fbo = 0; + + glDeleteTextures(1, &rt->copy_screen_effect.color); + rt->copy_screen_effect.color = 0; + } +} + +RID RasterizerStorageGLES2::render_target_create() { + + RenderTarget *rt = memnew(RenderTarget); + + Texture *t = memnew(Texture); + + t->flags = 0; + t->width = 0; + t->height = 0; + t->alloc_height = 0; + t->alloc_width = 0; + t->format = Image::FORMAT_R8; + t->target = GL_TEXTURE_2D; + t->gl_format_cache = 0; + t->gl_internal_format_cache = 0; + t->gl_type_cache = 0; + t->data_size = 0; + t->total_data_size = 0; + t->ignore_mipmaps = false; + t->mipmaps = 1; + t->active = true; + t->tex_id = 0; + t->render_target = rt; + + rt->texture = texture_owner.make_rid(t); + + return render_target_owner.make_rid(rt); +} + +void RasterizerStorageGLES2::render_target_set_size(RID p_render_target, int p_width, int p_height) { + + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND(!rt); + + if (p_width == rt->width && p_height == rt->height) + return; + + _render_target_clear(rt); + + rt->width = p_width; + rt->height = p_height; + + _render_target_allocate(rt); +} + +RID RasterizerStorageGLES2::render_target_get_texture(RID p_render_target) const { + + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND_V(!rt, RID()); + + return rt->texture; +} + +void RasterizerStorageGLES2::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) { + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND(!rt); + + rt->flags[p_flag] = p_value; + + switch (p_flag) { + case RENDER_TARGET_HDR: + case RENDER_TARGET_NO_3D: + case RENDER_TARGET_NO_SAMPLING: + case RENDER_TARGET_NO_3D_EFFECTS: { + //must reset for these formats + _render_target_clear(rt); + _render_target_allocate(rt); + + } break; + default: {} + } +} + +bool RasterizerStorageGLES2::render_target_was_used(RID p_render_target) { + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND_V(!rt, false); + + return rt->used_in_frame; +} + +void RasterizerStorageGLES2::render_target_clear_used(RID p_render_target) { + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND(!rt); + + rt->used_in_frame = false; +} + +void RasterizerStorageGLES2::render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa) { + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND(!rt); + + if (rt->msaa == p_msaa) + return; + + _render_target_clear(rt); + rt->msaa = p_msaa; + _render_target_allocate(rt); +} + +/* CANVAS SHADOW */ + +RID RasterizerStorageGLES2::canvas_light_shadow_buffer_create(int p_width) { + return RID(); +} + +/* LIGHT SHADOW MAPPING */ + +RID RasterizerStorageGLES2::canvas_light_occluder_create() { + return RID(); +} + +void RasterizerStorageGLES2::canvas_light_occluder_set_polylines(RID p_occluder, const PoolVector<Vector2> &p_lines) { +} + +VS::InstanceType RasterizerStorageGLES2::get_base_type(RID p_rid) const { + return VS::INSTANCE_NONE; +} + +bool RasterizerStorageGLES2::free(RID p_rid) { + return false; +} + +bool RasterizerStorageGLES2::has_os_feature(const String &p_feature) const { + return false; +} + +//////////////////////////////////////////// + +void RasterizerStorageGLES2::set_debug_generate_wireframes(bool p_generate) { +} + +void RasterizerStorageGLES2::render_info_begin_capture() { +} + +void RasterizerStorageGLES2::render_info_end_capture() { +} + +int RasterizerStorageGLES2::get_captured_render_info(VS::RenderInfo p_info) { + + return get_render_info(p_info); +} + +int RasterizerStorageGLES2::get_render_info(VS::RenderInfo p_info) { + return 0; +} + +void RasterizerStorageGLES2::initialize() { + RasterizerStorageGLES2::system_fbo = 0; + + { + const char *gl_extensions = (const char *)glGetString(GL_EXTENSIONS); + Vector<String> strings = String(gl_extensions).split(" ", false); + for (int i = 0; i < strings.size(); i++) { + config.extensions.insert(strings[i]); + } + } + + frame.count = 0; + frame.prev_tick = 0; + frame.delta = 0; + frame.current_rt = NULL; + frame.clear_request = false; + // config.keep_original_textures = false; + + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &config.max_texture_image_units); + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &config.max_texture_size); + + shaders.copy.init(); + + { + //default textures + + glGenTextures(1, &resources.white_tex); + unsigned char whitetexdata[8 * 8 * 3]; + for (int i = 0; i < 8 * 8 * 3; i++) { + whitetexdata[i] = 255; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, resources.white_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, whitetexdata); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + + glGenTextures(1, &resources.black_tex); + unsigned char blacktexdata[8 * 8 * 3]; + for (int i = 0; i < 8 * 8 * 3; i++) { + blacktexdata[i] = 0; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, resources.black_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, blacktexdata); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + + glGenTextures(1, &resources.normal_tex); + unsigned char normaltexdata[8 * 8 * 3]; + for (int i = 0; i < 8 * 8 * 3; i += 3) { + normaltexdata[i + 0] = 128; + normaltexdata[i + 1] = 128; + normaltexdata[i + 2] = 255; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, resources.normal_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, normaltexdata); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + + glGenTextures(1, &resources.aniso_tex); + unsigned char anisotexdata[8 * 8 * 3]; + for (int i = 0; i < 8 * 8 * 3; i += 3) { + anisotexdata[i + 0] = 255; + anisotexdata[i + 1] = 128; + anisotexdata[i + 2] = 0; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, resources.aniso_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, anisotexdata); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + } +} + +void RasterizerStorageGLES2::finalize() { +} + +void RasterizerStorageGLES2::update_dirty_resources() { + update_dirty_shaders(); + update_dirty_materials(); +} + +RasterizerStorageGLES2::RasterizerStorageGLES2() { + RasterizerStorageGLES2::system_fbo = 0; +} diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h new file mode 100644 index 0000000000..9f8d8d100b --- /dev/null +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -0,0 +1,838 @@ +/*************************************************************************/ +/* rasterizer_storage_gles2.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#ifndef RASTERIZERSTORAGEGLES2_H +#define RASTERIZERSTORAGEGLES2_H + +#include "self_list.h" +#include "servers/visual/rasterizer.h" +#include "servers/visual/shader_language.h" +#include "shader_compiler_gles2.h" +#include "shader_gles2.h" + +#include "shaders/copy.glsl.gen.h" +/* +#include "shaders/blend_shape.glsl.gen.h" +#include "shaders/canvas.glsl.gen.h" +#include "shaders/copy.glsl.gen.h" +#include "shaders/cubemap_filter.glsl.gen.h" +#include "shaders/particles.glsl.gen.h" +*/ + +class RasterizerCanvasGLES2; +class RasterizerSceneGLES2; + +class RasterizerStorageGLES2 : public RasterizerStorage { +public: + RasterizerCanvasGLES2 *canvas; + RasterizerSceneGLES2 *scene; + + static GLuint system_fbo; + + struct Config { + + bool shrink_textures_x2; + bool use_fast_texture_filter; + // bool use_anisotropic_filter; + + bool hdr_supported; + + bool use_rgba_2d_shadows; + + // float anisotropic_level; + + int max_texture_image_units; + int max_texture_size; + + bool generate_wireframes; + + bool use_texture_array_environment; + + Set<String> extensions; + + bool keep_original_textures; + + bool no_depth_prepass; + bool force_vertex_shading; + } config; + + struct Resources { + + GLuint white_tex; + GLuint black_tex; + GLuint normal_tex; + GLuint aniso_tex; + + GLuint quadie; + GLuint quadie_array; + + } resources; + + mutable struct Shaders { + + ShaderCompilerGLES2 compiler; + + CopyShaderGLES2 copy; + + ShaderCompilerGLES2::IdentifierActions actions_canvas; + ShaderCompilerGLES2::IdentifierActions actions_scene; + ShaderCompilerGLES2::IdentifierActions actions_particles; + + } shaders; + + struct Info { + + uint64_t texture_mem; + uint64_t vertex_mem; + + struct Render { + uint32_t object_count; + uint32_t draw_call_count; + uint32_t material_switch_count; + uint32_t surface_switch_count; + uint32_t shader_rebind_count; + uint32_t vertices_count; + + void reset() { + object_count = 0; + draw_call_count = 0; + material_switch_count = 0; + surface_switch_count = 0; + shader_rebind_count = 0; + vertices_count = 0; + } + } render, render_final, snap; + + Info() { + + texture_mem = 0; + vertex_mem = 0; + render.reset(); + render_final.reset(); + } + + } info; + + ///////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////DATA/////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////API//////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + + /* TEXTURE API */ + + struct RenderTarget; + + struct Texture : RID_Data { + + Texture *proxy; + Set<Texture *> proxy_owners; + + String path; + uint32_t flags; + int width, height; + int alloc_width, alloc_height; + Image::Format format; + + GLenum target; + GLenum gl_format_cache; + GLenum gl_internal_format_cache; + GLenum gl_type_cache; + + int data_size; + int total_data_size; + bool ignore_mipmaps; + + int mipmaps; + + bool active; + GLenum tex_id; + + uint16_t stored_cube_sides; + + RenderTarget *render_target; + + Ref<Image> images[6]; + + Texture() { + flags = 0; + width = 0; + height = 0; + alloc_width = 0; + alloc_height = 0; + format = Image::FORMAT_L8; + + target = 0; + + data_size = 0; + total_data_size = 0; + ignore_mipmaps = false; + + active = false; + + tex_id = 0; + + stored_cube_sides = 0; + + proxy = NULL; + + render_target = NULL; + } + + _ALWAYS_INLINE_ Texture *get_ptr() { + if (proxy) { + return proxy; //->get_ptr(); only one level of indirection, else not inlining possible. + } else { + return this; + } + } + + ~Texture() { + if (tex_id != 0) { + glDeleteTextures(1, &tex_id); + } + + for (Set<Texture *>::Element *E = proxy_owners.front(); E; E = E->next()) { + E->get()->proxy = NULL; + } + + if (proxy) { + proxy->proxy_owners.erase(this); + } + } + }; + + mutable RID_Owner<Texture> texture_owner; + + Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type); + + virtual RID texture_create(); + virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT); + virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT); + virtual Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const; + virtual void texture_set_flags(RID p_texture, uint32_t p_flags); + virtual uint32_t texture_get_flags(RID p_texture) const; + virtual Image::Format texture_get_format(RID p_texture) const; + virtual uint32_t texture_get_texid(RID p_texture) const; + virtual uint32_t texture_get_width(RID p_texture) const; + virtual uint32_t texture_get_height(RID p_texture) const; + virtual void texture_set_size_override(RID p_texture, int p_width, int p_height); + + virtual void texture_set_path(RID p_texture, const String &p_path); + virtual String texture_get_path(RID p_texture) const; + + virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable); + + virtual void texture_debug_usage(List<VS::TextureInfo> *r_info); + + virtual RID texture_create_radiance_cubemap(RID p_source, int p_resolution = -1) const; + + virtual void textures_keep_original(bool p_enable); + + virtual void texture_set_proxy(RID p_texture, RID p_proxy); + + virtual void texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); + virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); + virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata); + + /* SKY API */ + + virtual RID sky_create(); + virtual void sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size); + + /* SHADER API */ + + struct Material; + + struct Shader : public RID_Data { + + RID self; + + VS::ShaderMode mode; + ShaderGLES2 *shader; + String code; + SelfList<Material>::List materials; + + Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + + uint32_t texture_count; + + uint32_t custom_code_id; + uint32_t version; + + SelfList<Shader> dirty_list; + + Map<StringName, RID> default_textures; + + Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints; + + bool valid; + + String path; + + struct CanvasItem { + + enum BlendMode { + BLEND_MODE_MIX, + BLEND_MODE_ADD, + BLEND_MODE_SUB, + BLEND_MODE_MUL, + BLEND_MODE_PMALPHA, + }; + + int blend_mode; + + /* + enum LightMode { + LIGHT_MODE_NORMAL, + LIGHT_MODE_UNSHADED, + LIGHT_MODE_LIGHT_ONLY + }; + + int light_mode; + */ + bool uses_screen_texture; + bool uses_screen_uv; + bool uses_time; + + } canvas_item; + + /* + struct Spatial { + + enum BlendMode { + BLEND_MODE_MIX, + BLEND_MODE_ADD, + BLEND_MODE_SUB, + BLEND_MODE_MUL, + }; + + int blend_mode; + + enum DepthDrawMode { + DEPTH_DRAW_OPAQUE, + DEPTH_DRAW_ALWAYS, + DEPTH_DRAW_NEVER, + DEPTH_DRAW_ALPHA_PREPASS, + }; + + int depth_draw_mode; + + enum CullMode { + CULL_MODE_FRONT, + CULL_MODE_BACK, + CULL_MODE_DISABLED, + }; + + int cull_mode; + + bool uses_alpha; + bool uses_alpha_scissor; + bool unshaded; + bool no_depth_test; + bool uses_vertex; + bool uses_discard; + bool uses_sss; + bool uses_screen_texture; + bool uses_time; + bool writes_modelview_or_projection; + bool uses_vertex_lighting; + bool uses_world_coordinates; + + } spatial; + + struct Particles { + + } particles; + */ + + bool uses_vertex_time; + bool uses_fragment_time; + + Shader() : + dirty_list(this) { + + shader = NULL; + valid = false; + custom_code_id = 0; + version = 1; + } + }; + + mutable RID_Owner<Shader> shader_owner; + mutable SelfList<Shader>::List _shader_dirty_list; + + void _shader_make_dirty(Shader *p_shader); + + virtual RID shader_create(); + + virtual void shader_set_code(RID p_shader, const String &p_code); + virtual String shader_get_code(RID p_shader) const; + virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const; + + virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture); + virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const; + + void _update_shader(Shader *p_shader) const; + void update_dirty_shaders(); + + /* COMMON MATERIAL API */ + + struct Material : public RID_Data { + + Shader *shader; + Map<StringName, Variant> params; + SelfList<Material> list; + SelfList<Material> dirty_list; + Vector<RID> textures; + float line_width; + int render_priority; + + RID next_pass; + + uint32_t index; + uint64_t last_pass; + + Map<Geometry *, int> geometry_owners; + Map<RasterizerScene::InstanceBase *, int> instance_owners; + + bool can_cast_shadow_cache; + bool is_animated_cache; + + Material() : + list(this), + dirty_list(this) { + can_cast_shadow_cache = false; + is_animated_cache = false; + shader = NULL; + line_width = 1.0; + last_pass = 0; + render_priority = 0; + } + }; + + mutable SelfList<Material>::List _material_dirty_list; + void _material_make_dirty(Material *p_material) const; + + mutable RID_Owner<Material> material_owner; + + virtual RID material_create(); + + virtual void material_set_shader(RID p_material, RID p_shader); + virtual RID material_get_shader(RID p_material) const; + + virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value); + virtual Variant material_get_param(RID p_material, const StringName &p_param) const; + + virtual void material_set_line_width(RID p_material, float p_width); + virtual void material_set_next_pass(RID p_material, RID p_next_material); + + virtual bool material_is_animated(RID p_material); + virtual bool material_casts_shadows(RID p_material); + + virtual void material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance); + virtual void material_remove_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance); + + virtual void material_set_render_priority(RID p_material, int priority); + + void update_dirty_materials(); + + /* MESH API */ + virtual RID mesh_create(); + + virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()); + + virtual void mesh_set_blend_shape_count(RID p_mesh, int p_amount); + virtual int mesh_get_blend_shape_count(RID p_mesh) const; + + virtual void mesh_set_blend_shape_mode(RID p_mesh, VS::BlendShapeMode p_mode); + virtual VS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const; + + virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const PoolVector<uint8_t> &p_data); + + virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material); + virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const; + + virtual int mesh_surface_get_array_len(RID p_mesh, int p_surface) const; + virtual int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const; + + virtual PoolVector<uint8_t> mesh_surface_get_array(RID p_mesh, int p_surface) const; + virtual PoolVector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const; + + virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const; + virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const; + + virtual AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const; + virtual Vector<PoolVector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const; + virtual Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const; + + virtual void mesh_remove_surface(RID p_mesh, int p_surface); + virtual int mesh_get_surface_count(RID p_mesh) const; + + virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb); + virtual AABB mesh_get_custom_aabb(RID p_mesh) const; + + virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton) const; + virtual void mesh_clear(RID p_mesh); + + /* MULTIMESH API */ + + virtual RID multimesh_create(); + + virtual void multimesh_allocate(RID p_multimesh, int p_instances, VS::MultimeshTransformFormat p_transform_format, VS::MultimeshColorFormat p_color_format); + virtual int multimesh_get_instance_count(RID p_multimesh) const; + + virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh); + virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform); + virtual void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform); + virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color); + + virtual RID multimesh_get_mesh(RID p_multimesh) const; + + virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const; + virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const; + virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const; + + virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible); + virtual int multimesh_get_visible_instances(RID p_multimesh) const; + + virtual AABB multimesh_get_aabb(RID p_multimesh) const; + + void update_dirty_multimeshes(); + + /* IMMEDIATE API */ + + virtual RID immediate_create(); + virtual void immediate_begin(RID p_immediate, VS::PrimitiveType p_rimitive, RID p_texture = RID()); + virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex); + virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal); + virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent); + virtual void immediate_color(RID p_immediate, const Color &p_color); + virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv); + virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv); + virtual void immediate_end(RID p_immediate); + virtual void immediate_clear(RID p_immediate); + virtual void immediate_set_material(RID p_immediate, RID p_material); + virtual RID immediate_get_material(RID p_immediate) const; + virtual AABB immediate_get_aabb(RID p_immediate) const; + + /* SKELETON API */ + + void update_dirty_skeletons(); + + virtual RID skeleton_create(); + virtual void skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton = false); + virtual int skeleton_get_bone_count(RID p_skeleton) const; + virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform); + virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const; + virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform); + virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const; + + /* Light API */ + + virtual RID light_create(VS::LightType p_type); + + virtual void light_set_color(RID p_light, const Color &p_color); + virtual void light_set_param(RID p_light, VS::LightParam p_param, float p_value); + virtual void light_set_shadow(RID p_light, bool p_enabled); + virtual void light_set_shadow_color(RID p_light, const Color &p_color); + virtual void light_set_projector(RID p_light, RID p_texture); + virtual void light_set_negative(RID p_light, bool p_enable); + virtual void light_set_cull_mask(RID p_light, uint32_t p_mask); + virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled); + + virtual void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode); + virtual void light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail); + + virtual void light_directional_set_shadow_mode(RID p_light, VS::LightDirectionalShadowMode p_mode); + virtual void light_directional_set_blend_splits(RID p_light, bool p_enable); + virtual bool light_directional_get_blend_splits(RID p_light) const; + + virtual VS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light); + virtual VS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light); + + virtual void light_directional_set_shadow_depth_range_mode(RID p_light, VS::LightDirectionalShadowDepthRangeMode p_range_mode); + virtual VS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const; + + virtual bool light_has_shadow(RID p_light) const; + + virtual VS::LightType light_get_type(RID p_light) const; + virtual float light_get_param(RID p_light, VS::LightParam p_param); + virtual Color light_get_color(RID p_light); + + virtual AABB light_get_aabb(RID p_light) const; + virtual uint64_t light_get_version(RID p_light) const; + + /* PROBE API */ + virtual RID reflection_probe_create(); + + virtual void reflection_probe_set_update_mode(RID p_probe, VS::ReflectionProbeUpdateMode p_mode); + virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity); + virtual void reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient); + virtual void reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy); + virtual void reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib); + virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance); + virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents); + virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset); + virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable); + virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable); + virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable); + virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers); + + virtual AABB reflection_probe_get_aabb(RID p_probe) const; + virtual VS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const; + virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const; + + virtual Vector3 reflection_probe_get_extents(RID p_probe) const; + virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const; + virtual float reflection_probe_get_origin_max_distance(RID p_probe) const; + virtual bool reflection_probe_renders_shadows(RID p_probe) const; + + /* GI PROBE API */ + virtual RID gi_probe_create(); + + virtual void gi_probe_set_bounds(RID p_probe, const AABB &p_bounds); + virtual AABB gi_probe_get_bounds(RID p_probe) const; + + virtual void gi_probe_set_cell_size(RID p_probe, float p_size); + virtual float gi_probe_get_cell_size(RID p_probe) const; + + virtual void gi_probe_set_to_cell_xform(RID p_probe, const Transform &p_xform); + virtual Transform gi_probe_get_to_cell_xform(RID p_probe) const; + + virtual void gi_probe_set_dynamic_data(RID p_probe, const PoolVector<int> &p_data); + virtual PoolVector<int> gi_probe_get_dynamic_data(RID p_probe) const; + + virtual void gi_probe_set_dynamic_range(RID p_probe, int p_range); + virtual int gi_probe_get_dynamic_range(RID p_probe) const; + + virtual void gi_probe_set_energy(RID p_probe, float p_range); + virtual float gi_probe_get_energy(RID p_probe) const; + + virtual void gi_probe_set_bias(RID p_probe, float p_range); + virtual float gi_probe_get_bias(RID p_probe) const; + + virtual void gi_probe_set_normal_bias(RID p_probe, float p_range); + virtual float gi_probe_get_normal_bias(RID p_probe) const; + + virtual void gi_probe_set_propagation(RID p_probe, float p_range); + virtual float gi_probe_get_propagation(RID p_probe) const; + + virtual void gi_probe_set_interior(RID p_probe, bool p_enable); + virtual bool gi_probe_is_interior(RID p_probe) const; + + virtual void gi_probe_set_compress(RID p_probe, bool p_enable); + virtual bool gi_probe_is_compressed(RID p_probe) const; + + virtual uint32_t gi_probe_get_version(RID p_probe); + + virtual GIProbeCompression gi_probe_get_dynamic_data_get_preferred_compression() const; + virtual RID gi_probe_dynamic_data_create(int p_width, int p_height, int p_depth, GIProbeCompression p_compression); + virtual void gi_probe_dynamic_data_update(RID p_gi_probe_data, int p_depth_slice, int p_slice_count, int p_mipmap, const void *p_data); + + /* LIGHTMAP */ + + virtual RID lightmap_capture_create(); + virtual void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds); + virtual AABB lightmap_capture_get_bounds(RID p_capture) const; + virtual void lightmap_capture_set_octree(RID p_capture, const PoolVector<uint8_t> &p_octree); + virtual PoolVector<uint8_t> lightmap_capture_get_octree(RID p_capture) const; + virtual void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform); + virtual Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const; + virtual void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv); + virtual int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const; + virtual void lightmap_capture_set_energy(RID p_capture, float p_energy); + virtual float lightmap_capture_get_energy(RID p_capture) const; + virtual const PoolVector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const; + + /* PARTICLES */ + void update_particles(); + + virtual RID particles_create(); + + virtual void particles_set_emitting(RID p_particles, bool p_emitting); + virtual bool particles_get_emitting(RID p_particles); + + virtual void particles_set_amount(RID p_particles, int p_amount); + virtual void particles_set_lifetime(RID p_particles, float p_lifetime); + virtual void particles_set_one_shot(RID p_particles, bool p_one_shot); + virtual void particles_set_pre_process_time(RID p_particles, float p_time); + virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio); + virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio); + virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb); + virtual void particles_set_speed_scale(RID p_particles, float p_scale); + virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable); + virtual void particles_set_process_material(RID p_particles, RID p_material); + virtual void particles_set_fixed_fps(RID p_particles, int p_fps); + virtual void particles_set_fractional_delta(RID p_particles, bool p_enable); + virtual void particles_restart(RID p_particles); + + virtual void particles_set_draw_order(RID p_particles, VS::ParticlesDrawOrder p_order); + + virtual void particles_set_draw_passes(RID p_particles, int p_passes); + virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh); + + virtual void particles_request_process(RID p_particles); + virtual AABB particles_get_current_aabb(RID p_particles); + virtual AABB particles_get_aabb(RID p_particles) const; + + virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform); + + virtual int particles_get_draw_passes(RID p_particles) const; + virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const; + + /* INSTANCE */ + + virtual void instance_add_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance); + virtual void instance_remove_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance); + + virtual void instance_add_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance); + virtual void instance_remove_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance); + + /* RENDER TARGET */ + + struct RenderTarget : public RID_Data { + GLuint fbo; + + GLuint color; + GLuint depth; + + // TODO post processing effects? + + // TODO HDR? + + // TODO this is hardcoded for texscreen copies for now + + struct Effect { + GLuint fbo; + int width; + int height; + + GLuint color; + + Effect() { + fbo = 0; + width = 0; + height = 0; + color = 0; + } + }; + + Effect copy_screen_effect; + + int width, height; + + bool flags[RENDER_TARGET_FLAG_MAX]; + + bool used_in_frame; + VS::ViewportMSAA msaa; + + RID texture; + + RenderTarget() { + fbo = 0; + + color = 0; + depth = 0; + + width = 0; + height = 0; + + for (int i = 0; i < RENDER_TARGET_FLAG_MAX; i++) { + flags[i] = false; + } + + used_in_frame = false; + + msaa = VS::VIEWPORT_MSAA_DISABLED; + } + }; + + mutable RID_Owner<RenderTarget> render_target_owner; + + void _render_target_clear(RenderTarget *rt); + void _render_target_allocate(RenderTarget *rt); + + virtual RID render_target_create(); + virtual void render_target_set_size(RID p_render_target, int p_width, int p_height); + virtual RID render_target_get_texture(RID p_render_target) const; + + virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value); + virtual bool render_target_was_used(RID p_render_target); + virtual void render_target_clear_used(RID p_render_target); + virtual void render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa); + + /* CANVAS SHADOW */ + + virtual RID canvas_light_shadow_buffer_create(int p_width); + + /* LIGHT SHADOW MAPPING */ + + virtual RID canvas_light_occluder_create(); + virtual void canvas_light_occluder_set_polylines(RID p_occluder, const PoolVector<Vector2> &p_lines); + + virtual VS::InstanceType get_base_type(RID p_rid) const; + + virtual bool free(RID p_rid); + + struct Frame { + + RenderTarget *current_rt; + + bool clear_request; + Color clear_request_color; + int canvas_draw_commands; + float time[4]; + float delta; + uint64_t prev_tick; + uint64_t count; + + } frame; + + void initialize(); + void finalize(); + + virtual bool has_os_feature(const String &p_feature) const; + + virtual void update_dirty_resources(); + + virtual void set_debug_generate_wireframes(bool p_generate); + + virtual void render_info_begin_capture(); + virtual void render_info_end_capture(); + virtual int get_captured_render_info(VS::RenderInfo p_info); + + virtual int get_render_info(VS::RenderInfo p_info); + + RasterizerStorageGLES2(); +}; + +#endif // RASTERIZERSTORAGEGLES2_H diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp new file mode 100644 index 0000000000..f41bfe838b --- /dev/null +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -0,0 +1,891 @@ +/*************************************************************************/ +/* shader_compiler_gles3.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#include "shader_compiler_gles2.h" + +#include "os/os.h" +#include "string_buffer.h" +#include "string_builder.h" + +#define SL ShaderLanguage + +static String _mktab(int p_level) { + + String tb; + for (int i = 0; i < p_level; i++) { + tb += "\t"; + } + + return tb; +} + +static String _typestr(SL::DataType p_type) { + + return ShaderLanguage::get_datatype_name(p_type); +} + +static String _prestr(SL::DataPrecision p_pres) { + + switch (p_pres) { + case SL::PRECISION_LOWP: return "lowp "; + case SL::PRECISION_MEDIUMP: return "mediump "; + case SL::PRECISION_HIGHP: return "highp "; + case SL::PRECISION_DEFAULT: return ""; + } + return ""; +} + +static String _qualstr(SL::ArgumentQualifier p_qual) { + + switch (p_qual) { + case SL::ARGUMENT_QUALIFIER_IN: return "in "; + case SL::ARGUMENT_QUALIFIER_OUT: return "out "; + case SL::ARGUMENT_QUALIFIER_INOUT: return "inout "; + } + return ""; +} + +static String _opstr(SL::Operator p_op) { + + return SL::get_operator_text(p_op); +} + +static String _mkid(const String &p_id) { + + StringBuffer<> id; + id += "m_"; + id += p_id; + + return id.as_string(); +} + +static String f2sp0(float p_float) { + + if (int(p_float) == p_float) + return itos(p_float) + ".0"; + else + return rtoss(p_float); +} + +static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value> &p_values) { + + switch (p_type) { + case SL::TYPE_BOOL: return p_values[0].boolean ? "true" : "false"; + case SL::TYPE_BVEC2: + case SL::TYPE_BVEC3: + case SL::TYPE_BVEC4: { + + StringBuffer<> text; + + text += "bvec"; + text += itos(p_type - SL::TYPE_BOOL + 1); + text += "("; + + for (int i = 0; i < p_values.size(); i++) { + if (i > 0) + text += ","; + + text += p_values[i].boolean ? "true" : "false"; + } + text += ")"; + return text.as_string(); + } + + // GLSL ES 2 doesn't support uints, so we just use signed ints instead... + case SL::TYPE_UINT: return itos(p_values[0].uint); + case SL::TYPE_UVEC2: + case SL::TYPE_UVEC3: + case SL::TYPE_UVEC4: { + + StringBuffer<> text; + + text += "ivec"; + text += itos(p_type - SL::TYPE_UINT + 1); + text += "("; + + for (int i = 0; i < p_values.size(); i++) { + if (i > 0) + text += ","; + + text += itos(p_values[i].uint); + } + text += ")"; + return text.as_string(); + + } break; + + case SL::TYPE_INT: return itos(p_values[0].sint); + case SL::TYPE_IVEC2: + case SL::TYPE_IVEC3: + case SL::TYPE_IVEC4: { + + StringBuffer<> text; + + text += "ivec"; + text += itos(p_type - SL::TYPE_INT + 1); + text += "("; + + for (int i = 0; i < p_values.size(); i++) { + if (i > 0) + text += ","; + + text += itos(p_values[i].sint); + } + text += ")"; + return text.as_string(); + + } break; + case SL::TYPE_FLOAT: return f2sp0(p_values[0].real) + "f"; + case SL::TYPE_VEC2: + case SL::TYPE_VEC3: + case SL::TYPE_VEC4: { + + StringBuffer<> text; + + text += "vec"; + text += itos(p_type - SL::TYPE_FLOAT + 1); + text += "("; + + for (int i = 0; i < p_values.size(); i++) { + if (i > 0) + text += ","; + + text += f2sp0(p_values[i].real); + } + text += ")"; + return text.as_string(); + + } break; + case SL::TYPE_MAT2: + case SL::TYPE_MAT3: + case SL::TYPE_MAT4: { + + StringBuffer<> text; + + text += "mat"; + text += itos(p_type - SL::TYPE_MAT2 + 2); + text += "("; + + for (int i = 0; i < p_values.size(); i++) { + if (i > 0) + text += ","; + + text += f2sp0(p_values[i].real); + } + text += ")"; + return text.as_string(); + + } break; + default: ERR_FAIL_V(String()); + } +} + +void ShaderCompilerGLES2::_dump_function_deps(SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added) { + int fidx = -1; + + for (int i = 0; i < p_node->functions.size(); i++) { + if (p_node->functions[i].name == p_for_func) { + fidx = i; + break; + } + } + + ERR_FAIL_COND(fidx == -1); + + for (Set<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) { + + if (r_added.has(E->get())) { + continue; + } + + _dump_function_deps(p_node, E->get(), p_func_code, r_to_add, r_added); + + SL::FunctionNode *fnode = NULL; + + for (int i = 0; i < p_node->functions.size(); i++) { + if (p_node->functions[i].name == E->get()) { + fnode = p_node->functions[i].function; + break; + } + } + + ERR_FAIL_COND(!fnode); + + r_to_add += "\n"; + + StringBuffer<128> header; + + header += _typestr(fnode->return_type); + header += " "; + header += _mkid(fnode->name); + header += "("; + + for (int i = 0; i < fnode->arguments.size(); i++) { + if (i > 0) + header += ", "; + + header += _qualstr(fnode->arguments[i].qualifier); + header += _prestr(fnode->arguments[i].precision); + header += _typestr(fnode->arguments[i].type); + header += " "; + header += _mkid(fnode->arguments[i].name); + } + + header += ")\n"; + r_to_add += header.as_string(); + r_to_add += p_func_code[E->get()]; + + r_added.insert(E->get()); + } +} + +String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning) { + + StringBuilder code; + + switch (p_node->type) { + + case SL::Node::TYPE_SHADER: { + + SL::ShaderNode *snode = (SL::ShaderNode *)p_node; + + for (int i = 0; i < snode->render_modes.size(); i++) { + + if (p_default_actions.render_mode_defines.has(snode->render_modes[i]) && !used_rmode_defines.has(snode->render_modes[i])) { + + r_gen_code.custom_defines.push_back(p_default_actions.render_mode_defines[snode->render_modes[i]].utf8()); + used_rmode_defines.insert(snode->render_modes[i]); + } + + if (p_actions.render_mode_flags.has(snode->render_modes[i])) { + *p_actions.render_mode_flags[snode->render_modes[i]] = true; + } + + if (p_actions.render_mode_values.has(snode->render_modes[i])) { + Pair<int *, int> &p = p_actions.render_mode_values[snode->render_modes[i]]; + *p.first = p.second; + } + } + + int max_texture_uniforms = 0; + int max_uniforms = 0; + + for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = snode->uniforms.front(); E; E = E->next()) { + if (SL::is_sampler_type(E->get().type)) + max_texture_uniforms++; + else + max_uniforms++; + } + + r_gen_code.texture_uniforms.resize(max_texture_uniforms); + r_gen_code.texture_hints.resize(max_texture_uniforms); + + r_gen_code.uniforms.resize(max_uniforms + max_texture_uniforms); + + StringBuilder vertex_global; + StringBuilder fragment_global; + + // uniforms + + for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = snode->uniforms.front(); E; E = E->next()) { + StringBuffer<> uniform_code; + + uniform_code += "uniform "; + + uniform_code += _prestr(E->get().precission); + uniform_code += _typestr(E->get().type); + uniform_code += " "; + uniform_code += _mkid(E->key()); + uniform_code += ";\n"; + + if (SL::is_sampler_type(E->get().type)) { + r_gen_code.texture_uniforms[E->get().texture_order] = _mkid(E->key()); + r_gen_code.texture_hints[E->get().texture_order] = E->get().hint; + } else { + r_gen_code.uniforms[E->get().order] = E->key(); + } + + vertex_global += uniform_code.as_string(); + fragment_global += uniform_code.as_string(); + + p_actions.uniforms->insert(E->key(), E->get()); + } + + // varyings + + for (Map<StringName, SL::ShaderNode::Varying>::Element *E = snode->varyings.front(); E; E = E->next()) { + + StringBuffer<> varying_code; + + varying_code += "varying "; + varying_code += _prestr(E->get().precission); + varying_code += _typestr(E->get().type); + varying_code += " "; + varying_code += _mkid(E->key()); + varying_code += ";\n"; + + String final_code = varying_code.as_string(); + + vertex_global += final_code; + fragment_global += final_code; + } + + // functions + + Map<StringName, String> function_code; + + for (int i = 0; i < snode->functions.size(); i++) { + SL::FunctionNode *fnode = snode->functions[i].function; + function_code[fnode->name] = _dump_node_code(fnode->body, 1, r_gen_code, p_actions, p_default_actions, p_assigning); + } + + Set<StringName> added_vertex; + Set<StringName> added_fragment; + + for (int i = 0; i < snode->functions.size(); i++) { + + SL::FunctionNode *fnode = snode->functions[i].function; + + current_func_name = fnode->name; + + if (fnode->name == vertex_name) { + _dump_function_deps(snode, fnode->name, function_code, vertex_global, added_vertex); + r_gen_code.vertex = function_code[vertex_name]; + + } else if (fnode->name == fragment_name) { + _dump_function_deps(snode, fnode->name, function_code, fragment_global, added_fragment); + r_gen_code.fragment = function_code[fragment_name]; + + } else if (fnode->name == light_name) { + _dump_function_deps(snode, fnode->name, function_code, fragment_global, added_fragment); + r_gen_code.light = function_code[light_name]; + } + } + + r_gen_code.vertex_global = vertex_global.as_string(); + r_gen_code.fragment_global = fragment_global.as_string(); + + } break; + + case SL::Node::TYPE_FUNCTION: { + + } break; + + case SL::Node::TYPE_BLOCK: { + + SL::BlockNode *bnode = (SL::BlockNode *)p_node; + + if (!bnode->single_statement) { + code += _mktab(p_level - 1); + code += "{\n"; + } + + for (int i = 0; i < bnode->statements.size(); i++) { + String statement_code = _dump_node_code(bnode->statements[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + + if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement) { + code += statement_code; + } else { + code += _mktab(p_level); + code += statement_code; + code += ";\n"; + } + } + + if (!bnode->single_statement) { + code += _mktab(p_level - 1); + code += "}\n"; + } + } break; + + case SL::Node::TYPE_VARIABLE_DECLARATION: { + SL::VariableDeclarationNode *var_dec_node = (SL::VariableDeclarationNode *)p_node; + + StringBuffer<> declaration; + + declaration += _prestr(var_dec_node->precision); + declaration += _typestr(var_dec_node->datatype); + + for (int i = 0; i < var_dec_node->declarations.size(); i++) { + + if (i > 0) { + declaration += ","; + } + + declaration += " "; + + declaration += _mkid(var_dec_node->declarations[i].name); + + if (var_dec_node->declarations[i].initializer) { + declaration += " = "; + declaration += _dump_node_code(var_dec_node->declarations[i].initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } + } + + code += declaration.as_string(); + } break; + + case SL::Node::TYPE_VARIABLE: { + SL::VariableNode *var_node = (SL::VariableNode *)p_node; + + if (p_assigning && p_actions.write_flag_pointers.has(var_node->name)) { + *p_actions.write_flag_pointers[var_node->name] = true; + } + + if (p_default_actions.usage_defines.has(var_node->name) && !used_name_defines.has(var_node->name)) { + String define = p_default_actions.usage_defines[var_node->name]; + + if (define.begins_with("@")) { + define = p_default_actions.usage_defines[define.substr(1, define.length())]; + } + + r_gen_code.custom_defines.push_back(define.utf8()); + used_name_defines.insert(var_node->name); + } + + if (p_actions.usage_flag_pointers.has(var_node->name) && !used_flag_pointers.has(var_node->name)) { + *p_actions.usage_flag_pointers[var_node->name] = true; + used_flag_pointers.insert(var_node->name); + } + + if (p_default_actions.renames.has(var_node->name)) { + code += p_default_actions.renames[var_node->name]; + } else { + code += _mkid(var_node->name); + } + + if (var_node->name == time_name) { + if (current_func_name == vertex_name) { + r_gen_code.uses_vertex_time = true; + } + if (current_func_name == fragment_name || current_func_name == light_name) { + r_gen_code.uses_fragment_time = true; + } + } + } break; + + case SL::Node::TYPE_CONSTANT: { + SL::ConstantNode *const_node = (SL::ConstantNode *)p_node; + + return get_constant_text(const_node->datatype, const_node->values); + } break; + + case SL::Node::TYPE_OPERATOR: { + SL::OperatorNode *op_node = (SL::OperatorNode *)p_node; + + switch (op_node->op) { + case SL::OP_ASSIGN: + case SL::OP_ASSIGN_ADD: + case SL::OP_ASSIGN_SUB: + case SL::OP_ASSIGN_MUL: + case SL::OP_ASSIGN_DIV: + case SL::OP_ASSIGN_SHIFT_LEFT: + case SL::OP_ASSIGN_SHIFT_RIGHT: + case SL::OP_ASSIGN_MOD: + case SL::OP_ASSIGN_BIT_AND: + case SL::OP_ASSIGN_BIT_OR: + case SL::OP_ASSIGN_BIT_XOR: { + code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, true); + code += " "; + code += _opstr(op_node->op); + code += " "; + code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } break; + + case SL::OP_BIT_INVERT: + case SL::OP_NEGATE: + case SL::OP_NOT: + case SL::OP_DECREMENT: + case SL::OP_INCREMENT: { + code += _opstr(op_node->op); + code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } break; + + case SL::OP_POST_DECREMENT: + case SL::OP_POST_INCREMENT: { + code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _opstr(op_node->op); + } break; + + case SL::OP_CALL: + case SL::OP_CONSTRUCT: { + ERR_FAIL_COND_V(op_node->arguments[0]->type != SL::Node::TYPE_VARIABLE, String()); + + SL::VariableNode *var_node = (SL::VariableNode *)op_node->arguments[0]; + + if (op_node->op == SL::OP_CONSTRUCT) { + code += var_node->name; + } else { + + if (var_node->name == "texture") { + // emit texture call + + if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER2D) { + code += "texture2D"; + } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLERCUBE) { + code += "textureCube"; + } + + } else if (p_default_actions.renames.has(var_node->name)) { + code += p_default_actions.renames[var_node->name]; + } else if (internal_functions.has(var_node->name)) { + code += var_node->name; + } else { + code += _mkid(var_node->name); + } + } + + code += "("; + + for (int i = 1; i < op_node->arguments.size(); i++) { + if (i > 1) { + code += ", "; + } + + code += _dump_node_code(op_node->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } + + code += ")"; + + } break; + + case SL::OP_INDEX: { + code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += "["; + code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += "]"; + } break; + + case SL::OP_SELECT_IF: { + code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += " ? "; + code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += " : "; + code += _dump_node_code(op_node->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } break; + + default: { + code += "("; + code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += " "; + code += _opstr(op_node->op); + code += " "; + code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += ")"; + } break; + } + } break; + + case SL::Node::TYPE_CONTROL_FLOW: { + SL::ControlFlowNode *cf_node = (SL::ControlFlowNode *)p_node; + + if (cf_node->flow_op == SL::FLOW_OP_IF) { + + code += _mktab(p_level); + code += "if ("; + code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += ")\n"; + code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); + + if (cf_node->blocks.size() == 2) { + code += _mktab(p_level); + code += "else\n"; + code += _dump_node_code(cf_node->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); + } + } else if (cf_node->flow_op == SL::FLOW_OP_WHILE) { + code += _mktab(p_level); + code += "while ("; + code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += ")\n"; + code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); + } else if (cf_node->flow_op == SL::FLOW_OP_FOR) { + + code += _mktab(p_level); + code += "for ("; + code += _dump_node_code(cf_node->blocks[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += "; "; + code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += "; "; + code += _dump_node_code(cf_node->expressions[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += ")\n"; + + code += _dump_node_code(cf_node->blocks[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + + } else if (cf_node->flow_op == SL::FLOW_OP_RETURN) { + code += _mktab(p_level); + code += "return"; + + if (cf_node->expressions.size()) { + code += " "; + code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } + code += ";\n"; + } else if (cf_node->flow_op == SL::FLOW_OP_DISCARD) { + code += "discard;"; + } else if (cf_node->flow_op == SL::FLOW_OP_CONTINUE) { + code += "continue;"; + } else if (cf_node->flow_op == SL::FLOW_OP_BREAK) { + code += "break;"; + } + } break; + + case SL::Node::TYPE_MEMBER: { + SL::MemberNode *member_node = (SL::MemberNode *)p_node; + code += _dump_node_code(member_node->owner, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += "."; + code += member_node->name; + } break; + } + + return code.as_string(); +} + +Error ShaderCompilerGLES2::compile(VS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) { + + Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types()); + + if (err != OK) { + + Vector<String> shader = p_code.split("\n"); + for (int i = 0; i < shader.size(); i++) { + print_line(itos(i) + " " + shader[i]); + } + + _err_print_error(NULL, p_path.utf8().get_data(), parser.get_error_line(), parser.get_error_text().utf8().get_data(), ERR_HANDLER_SHADER); + return err; + } + + r_gen_code.custom_defines.clear(); + r_gen_code.uniforms.clear(); + r_gen_code.texture_uniforms.clear(); + r_gen_code.texture_hints.clear(); + r_gen_code.vertex = String(); + r_gen_code.vertex_global = String(); + r_gen_code.fragment = String(); + r_gen_code.fragment_global = String(); + r_gen_code.light = String(); + r_gen_code.uses_fragment_time = false; + r_gen_code.uses_vertex_time = false; + + used_name_defines.clear(); + used_rmode_defines.clear(); + used_flag_pointers.clear(); + + _dump_node_code(parser.get_shader(), 1, r_gen_code, *p_actions, actions[p_mode], false); + + return OK; +} + +ShaderCompilerGLES2::ShaderCompilerGLES2() { + + /** CANVAS ITEM SHADER **/ + + actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy"; + actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv_interp"; + actions[VS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "gl_PointSize"; + + actions[VS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"] = "modelview_matrix"; + actions[VS::SHADER_CANVAS_ITEM].renames["PROJECTION_MATRIX"] = "projection_matrix"; + actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] == "extra_matrix"; + actions[VS::SHADER_CANVAS_ITEM].renames["TIME"] = "time"; + actions[VS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass"; + actions[VS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom"; + + actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color"; + actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal"; + actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP"] = "normal_map"; + actions[VS::SHADER_CANVAS_ITEM].renames["NORMALMAP_DEPTH"] = "normal_depth"; + actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv_interp"; + actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color"; + actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE"] = "color_texture"; + actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE_PIXEL_SIZE"] = "color_texpixel_size"; + actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL_TEXTURE"] = "normal_texture"; + actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_UV"] = "screen_uv"; + actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_TEXTURE"] = "screen_texture"; + actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_PIXEL_SIZE"] = "screen_pixel_size"; + actions[VS::SHADER_CANVAS_ITEM].renames["FRAGCOORD"] = "gl_FragCoord"; + actions[VS::SHADER_CANVAS_ITEM].renames["POINT_COORD"] = "gl_PointCoord"; + + actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_VEC"] = "light_vec"; + actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_HEIGHT"] = "light_height"; + actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_COLOR"] = "light_color"; + actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_UV"] = "light_uv"; + //actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_SHADOW_COLOR"]="light_shadow_color"; + actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT"] = "light"; + actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_COLOR"] = "shadow_color"; + + actions[VS::SHADER_CANVAS_ITEM].usage_defines["COLOR"] = "#define COLOR_USED\n"; + actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n"; + actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n"; + actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_PIXEL_SIZE"] = "@SCREEN_UV"; + actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"] = "#define NORMAL_USED\n"; + actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n"; + actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_COLOR"] = "#define SHADOW_COLOR_USED\n"; + actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; + + actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; + + /** SPATIAL SHADER **/ + + actions[VS::SHADER_SPATIAL].renames["WORLD_MATRIX"] = "world_transform"; + actions[VS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"] = "camera_inverse_matrix"; + actions[VS::SHADER_SPATIAL].renames["CAMERA_MATRIX"] = "camera_matrix"; + actions[VS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"] = "projection_matrix"; + actions[VS::SHADER_SPATIAL].renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix"; + actions[VS::SHADER_SPATIAL].renames["MODELVIEW_MATRIX"] = "modelview"; + + actions[VS::SHADER_SPATIAL].renames["VERTEX"] = "vertex.xyz"; + actions[VS::SHADER_SPATIAL].renames["NORMAL"] = "normal"; + actions[VS::SHADER_SPATIAL].renames["TANGENT"] = "tangent"; + actions[VS::SHADER_SPATIAL].renames["BINORMAL"] = "binormal"; + actions[VS::SHADER_SPATIAL].renames["UV"] = "uv_interp"; + actions[VS::SHADER_SPATIAL].renames["UV2"] = "uv2_interp"; + actions[VS::SHADER_SPATIAL].renames["COLOR"] = "color_interp"; + actions[VS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize"; + //actions[VS::SHADER_SPATIAL].renames["INSTANCE_ID"]=ShaderLanguage::TYPE_INT; + + //builtins + + actions[VS::SHADER_SPATIAL].renames["TIME"] = "time"; + actions[VS::SHADER_SPATIAL].renames["VIEWPORT_SIZE"] = "viewport_size"; + + actions[VS::SHADER_SPATIAL].renames["FRAGCOORD"] = "gl_FragCoord"; + actions[VS::SHADER_SPATIAL].renames["FRONT_FACING"] = "gl_FrontFacing"; + actions[VS::SHADER_SPATIAL].renames["NORMALMAP"] = "normalmap"; + actions[VS::SHADER_SPATIAL].renames["NORMALMAP_DEPTH"] = "normaldepth"; + actions[VS::SHADER_SPATIAL].renames["ALBEDO"] = "albedo"; + actions[VS::SHADER_SPATIAL].renames["ALPHA"] = "alpha"; + actions[VS::SHADER_SPATIAL].renames["METALLIC"] = "metallic"; + actions[VS::SHADER_SPATIAL].renames["SPECULAR"] = "specular"; + actions[VS::SHADER_SPATIAL].renames["ROUGHNESS"] = "roughness"; + actions[VS::SHADER_SPATIAL].renames["RIM"] = "rim"; + actions[VS::SHADER_SPATIAL].renames["RIM_TINT"] = "rim_tint"; + actions[VS::SHADER_SPATIAL].renames["CLEARCOAT"] = "clearcoat"; + actions[VS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss"; + actions[VS::SHADER_SPATIAL].renames["ANISOTROPY"] = "anisotropy"; + actions[VS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; + //actions[VS::SHADER_SPATIAL].renames["SSS_SPREAD"] = "sss_spread"; + actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength"; + actions[VS::SHADER_SPATIAL].renames["TRANSMISSION"] = "transmission"; + actions[VS::SHADER_SPATIAL].renames["AO"] = "ao"; + actions[VS::SHADER_SPATIAL].renames["AO_LIGHT_AFFECT"] = "ao_light_affect"; + actions[VS::SHADER_SPATIAL].renames["EMISSION"] = "emission"; + //actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2; + actions[VS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord"; + actions[VS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom"; + actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv"; + actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture"; + actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer"; + actions[VS::SHADER_SPATIAL].renames["SIDE"] = "side"; + actions[VS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor"; + + //for light + actions[VS::SHADER_SPATIAL].renames["VIEW"] = "view"; + actions[VS::SHADER_SPATIAL].renames["LIGHT_COLOR"] = "light_color"; + actions[VS::SHADER_SPATIAL].renames["ATTENUATION"] = "attenuation"; + actions[VS::SHADER_SPATIAL].renames["DIFFUSE_LIGHT"] = "diffuse_light"; + actions[VS::SHADER_SPATIAL].renames["SPECULAR_LIGHT"] = "specular_light"; + + actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n"; + actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT"; + actions[VS::SHADER_SPATIAL].usage_defines["RIM"] = "#define LIGHT_USE_RIM\n"; + actions[VS::SHADER_SPATIAL].usage_defines["RIM_TINT"] = "@RIM"; + actions[VS::SHADER_SPATIAL].usage_defines["CLEARCOAT"] = "#define LIGHT_USE_CLEARCOAT\n"; + actions[VS::SHADER_SPATIAL].usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT"; + actions[VS::SHADER_SPATIAL].usage_defines["ANISOTROPY"] = "#define LIGHT_USE_ANISOTROPY\n"; + actions[VS::SHADER_SPATIAL].usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY"; + actions[VS::SHADER_SPATIAL].usage_defines["AO"] = "#define ENABLE_AO\n"; + actions[VS::SHADER_SPATIAL].usage_defines["AO_LIGHT_AFFECT"] = "#define ENABLE_AO\n"; + actions[VS::SHADER_SPATIAL].usage_defines["UV"] = "#define ENABLE_UV_INTERP\n"; + actions[VS::SHADER_SPATIAL].usage_defines["UV2"] = "#define ENABLE_UV2_INTERP\n"; + actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP"] = "#define ENABLE_NORMALMAP\n"; + actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP"; + actions[VS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n"; + actions[VS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n"; + actions[VS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n"; + + actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n"; + actions[VS::SHADER_SPATIAL].usage_defines["TRANSMISSION"] = "#define TRANSMISSION_USED\n"; + actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n"; + actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n"; + + actions[VS::SHADER_SPATIAL].usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; + actions[VS::SHADER_SPATIAL].usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; + + actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength"; + + actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; + + actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; + + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; + + /* PARTICLES SHADER */ + + actions[VS::SHADER_PARTICLES].renames["COLOR"] = "out_color"; + actions[VS::SHADER_PARTICLES].renames["VELOCITY"] = "out_velocity_active.xyz"; + actions[VS::SHADER_PARTICLES].renames["MASS"] = "mass"; + actions[VS::SHADER_PARTICLES].renames["ACTIVE"] = "active"; + actions[VS::SHADER_PARTICLES].renames["RESTART"] = "restart"; + actions[VS::SHADER_PARTICLES].renames["CUSTOM"] = "out_custom"; + actions[VS::SHADER_PARTICLES].renames["TRANSFORM"] = "xform"; + actions[VS::SHADER_PARTICLES].renames["TIME"] = "time"; + actions[VS::SHADER_PARTICLES].renames["LIFETIME"] = "lifetime"; + actions[VS::SHADER_PARTICLES].renames["DELTA"] = "local_delta"; + actions[VS::SHADER_PARTICLES].renames["NUMBER"] = "particle_number"; + actions[VS::SHADER_PARTICLES].renames["INDEX"] = "index"; + actions[VS::SHADER_PARTICLES].renames["GRAVITY"] = "current_gravity"; + actions[VS::SHADER_PARTICLES].renames["EMISSION_TRANSFORM"] = "emission_transform"; + actions[VS::SHADER_PARTICLES].renames["RANDOM_SEED"] = "random_seed"; + + actions[VS::SHADER_SPATIAL].render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n"; + + vertex_name = "vertex"; + fragment_name = "fragment"; + light_name = "light"; + time_name = "TIME"; + + List<String> func_list; + + ShaderLanguage::get_builtin_funcs(&func_list); + + for (List<String>::Element *E = func_list.front(); E; E = E->next()) { + internal_functions.insert(E->get()); + } +} diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h new file mode 100644 index 0000000000..804ead2172 --- /dev/null +++ b/drivers/gles2/shader_compiler_gles2.h @@ -0,0 +1,101 @@ +/*************************************************************************/ +/* shader_compiler_gles2.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#ifndef SHADERCOMPILERGLES2_H +#define SHADERCOMPILERGLES2_H + +#include "pair.h" +#include "servers/visual/shader_language.h" +#include "servers/visual/shader_types.h" +#include "servers/visual_server.h" + +#include "string_builder.h" + +class ShaderCompilerGLES2 { +public: + struct IdentifierActions { + + Map<StringName, Pair<int *, int> > render_mode_values; + Map<StringName, bool *> render_mode_flags; + Map<StringName, bool *> usage_flag_pointers; + Map<StringName, bool *> write_flag_pointers; + + Map<StringName, ShaderLanguage::ShaderNode::Uniform> *uniforms; + }; + + struct GeneratedCode { + + Vector<CharString> custom_defines; + Vector<StringName> uniforms; + Vector<StringName> texture_uniforms; + Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints; + + String vertex_global; + String vertex; + String fragment_global; + String fragment; + String light; + + bool uses_fragment_time; + bool uses_vertex_time; + }; + +private: + ShaderLanguage parser; + + struct DefaultIdentifierActions { + + Map<StringName, String> renames; + Map<StringName, String> render_mode_defines; + Map<StringName, String> usage_defines; + }; + + void _dump_function_deps(ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added); + String _dump_node_code(ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning); + + StringName current_func_name; + StringName vertex_name; + StringName fragment_name; + StringName light_name; + StringName time_name; + + Set<StringName> used_name_defines; + Set<StringName> used_flag_pointers; + Set<StringName> used_rmode_defines; + Set<StringName> internal_functions; + + DefaultIdentifierActions actions[VS::SHADER_MAX]; + +public: + Error compile(VS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code); + + ShaderCompilerGLES2(); +}; + +#endif // SHADERCOMPILERGLES3_H diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp new file mode 100644 index 0000000000..fa9562877d --- /dev/null +++ b/drivers/gles2/shader_gles2.cpp @@ -0,0 +1,689 @@ +/*************************************************************************/ +/* shader_gles2.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#include "shader_gles2.h" + +#include "memory.h" +#include "print_string.h" +#include "string_builder.h" + +//#define DEBUG_OPENGL + +// #include "shaders/copy.glsl.gen.h" + +#ifdef DEBUG_OPENGL + +#define DEBUG_TEST_ERROR(m_section) \ + { \ + uint32_t err = glGetError(); \ + if (err) { \ + print_line("OpenGL Error #" + itos(err) + " at: " + m_section); \ + } \ + } +#else + +#define DEBUG_TEST_ERROR(m_section) + +#endif + +ShaderGLES2 *ShaderGLES2::active = NULL; + +//#define DEBUG_SHADER + +#ifdef DEBUG_SHADER + +#define DEBUG_PRINT(m_text) print_line(m_text); + +#else + +#define DEBUG_PRINT(m_text) + +#endif + +void ShaderGLES2::bind_uniforms() { + if (!uniforms_dirty) + return; + + // regular uniforms + + const Map<uint32_t, Variant>::Element *E = uniform_defaults.front(); + + while (E) { + int idx = E->key(); + int location = version->uniform_location[idx]; + + if (location < 0) { + E = E->next(); + continue; + } + + const Variant &v = E->value(); + _set_uniform_variant(location, v); + E = E->next(); + } + + // camera uniforms + + const Map<uint32_t, CameraMatrix>::Element *C = uniform_cameras.front(); + + while (C) { + int idx = E->key(); + int location = version->uniform_location[idx]; + + if (location < 0) { + C = C->next(); + continue; + } + + glUniformMatrix4fv(location, 1, GL_FALSE, &(C->get().matrix[0][0])); + C = C->next(); + } + + uniforms_dirty = false; +} + +GLint ShaderGLES2::get_uniform_location(int p_index) const { + + ERR_FAIL_COND_V(!version, -1); + + return version->uniform_location[p_index]; +} + +bool ShaderGLES2::bind() { + + if (active != this || !version || new_conditional_version.key != conditional_version.key) { + conditional_version = new_conditional_version; + version = get_current_version(); + } else { + return false; + } + + ERR_FAIL_COND_V(!version, false); + + glUseProgram(version->id); + + DEBUG_TEST_ERROR("use program"); + + active = this; + uniforms_dirty = true; + + return true; +} + +void ShaderGLES2::unbind() { + version = NULL; + glUseProgram(0); + uniforms_dirty = true; + active = NULL; +} + +static String _fix_error_code_line(const String &p_error, int p_code_start, int p_offset) { + + int last_find_pos = -1; + // NVIDIA + String error = p_error; + while ((last_find_pos = p_error.find("(", last_find_pos + 1)) != -1) { + + int end_pos = last_find_pos + 1; + + while (true) { + + if (p_error[end_pos] >= '0' && p_error[end_pos] <= '9') { + + end_pos++; + continue; + } else if (p_error[end_pos] == ')') { + break; + } else { + + end_pos = -1; + break; + } + } + + if (end_pos == -1) + continue; + + String numstr = error.substr(last_find_pos + 1, (end_pos - last_find_pos) - 1); + String begin = error.substr(0, last_find_pos + 1); + String end = error.substr(end_pos, error.length()); + int num = numstr.to_int() + p_code_start - p_offset; + error = begin + itos(num) + end; + } + + // ATI + last_find_pos = -1; + while ((last_find_pos = p_error.find("ERROR: ", last_find_pos + 1)) != -1) { + + last_find_pos += 6; + int end_pos = last_find_pos + 1; + + while (true) { + + if (p_error[end_pos] >= '0' && p_error[end_pos] <= '9') { + + end_pos++; + continue; + } else if (p_error[end_pos] == ':') { + break; + } else { + + end_pos = -1; + break; + } + } + continue; + if (end_pos == -1) + continue; + + String numstr = error.substr(last_find_pos + 1, (end_pos - last_find_pos) - 1); + print_line("numstr: " + numstr); + String begin = error.substr(0, last_find_pos + 1); + String end = error.substr(end_pos, error.length()); + int num = numstr.to_int() + p_code_start - p_offset; + error = begin + itos(num) + end; + } + return error; +} + +ShaderGLES2::Version *ShaderGLES2::get_current_version() { + + Version *_v = version_map.getptr(conditional_version); + + if (_v) { + if (conditional_version.code_version != 0) { + CustomCode *cc = custom_code_map.getptr(conditional_version.code_version); + ERR_FAIL_COND_V(!cc, _v); + if (cc->version == _v->code_version) + return _v; + } else { + return _v; + } + } + + if (!_v) + version_map[conditional_version]; + + Version &v = version_map[conditional_version]; + + if (!_v) { + v.uniform_location = memnew_arr(GLint, uniform_count); + } else { + if (v.ok) { + glDeleteShader(v.vert_id); + glDeleteShader(v.frag_id); + glDeleteProgram(v.id); + v.id = 0; + } + } + + v.ok = false; + + Vector<const char *> strings; + +#ifdef GLES_OVER_GL + strings.push_back("#version 120\n"); + strings.push_back("#define USE_GLES_OVER_GL\n"); +#else + strings.push_back("#version 100\n"); +#endif + + int define_line_ofs = 1; + + for (int j = 0; j < conditional_count; j++) { + bool enable = (conditional_version.version & (1 << j)) > 0; + + if (enable) { + strings.push_back(conditional_defines[j]); + define_line_ofs++; + DEBUG_PRINT(conditional_defines[j]); + } + } + + // keep them around during the functino + CharString code_string; + CharString code_string2; + CharString code_globals; + + CustomCode *cc = NULL; + + if (conditional_version.code_version > 0) { + cc = custom_code_map.getptr(conditional_version.code_version); + + ERR_FAIL_COND_V(!cc, NULL); + v.code_version = cc->version; + define_line_ofs += 2; + } + + // program + + v.id = glCreateProgram(); + ERR_FAIL_COND_V(v.id == 0, NULL); + + if (cc) { + for (int i = 0; i < cc->custom_defines.size(); i++) { + strings.push_back(cc->custom_defines[i]); + DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i])); + } + } + + // vertex shader + + int string_base_size = strings.size(); + + strings.push_back(vertex_code0.get_data()); + + if (cc) { + code_globals = cc->vertex_globals.ascii(); + strings.push_back(code_globals.get_data()); + } + + strings.push_back(vertex_code1.get_data()); + + if (cc) { + code_string = cc->vertex.ascii(); + strings.push_back(code_string.get_data()); + } + + strings.push_back(vertex_code2.get_data()); + +#ifdef DEBUG_SHADER + + DEBUG_PRINT("\nVertex Code:\n\n" + String(code_string.get_data())); + +#endif + + v.vert_id = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(v.vert_id, strings.size(), &strings[0], NULL); + glCompileShader(v.vert_id); + + GLint status; + + glGetShaderiv(v.vert_id, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + GLsizei iloglen; + glGetShaderiv(v.vert_id, GL_INFO_LOG_LENGTH, &iloglen); + + if (iloglen < 0) { + glDeleteShader(v.vert_id); + glDeleteProgram(v.id); + v.id = 0; + + ERR_PRINT("No OpenGL vertex shader compiler log. What the frick?"); + } else { + if (iloglen == 0) { + iloglen = 4096; // buggy driver (Adreno 220+) + } + + char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); + ilogmem[iloglen] = '\0'; + glGetShaderInfoLog(v.vert_id, iloglen, &iloglen, ilogmem); + + String err_string = get_shader_name() + ": Vertex shader compilation failed:\n"; + + err_string += ilogmem; + err_string = _fix_error_code_line(err_string, vertex_code_start, define_line_ofs); + + ERR_PRINTS(err_string); + + Memory::free_static(ilogmem); + glDeleteShader(v.vert_id); + glDeleteProgram(v.id); + v.id = 0; + } + + ERR_FAIL_V(NULL); + } + + strings.resize(string_base_size); + + // fragment shader + + strings.push_back(fragment_code0.get_data()); + + if (cc) { + code_globals = cc->fragment_globals.ascii(); + strings.push_back(code_globals.get_data()); + } + + strings.push_back(fragment_code1.get_data()); + + if (cc) { + code_string = cc->fragment.ascii(); + strings.push_back(code_string.get_data()); + } + + strings.push_back(fragment_code2.get_data()); + + if (cc) { + code_string2 = cc->light.ascii(); + strings.push_back(code_string2.get_data()); + } + + strings.push_back(fragment_code3.get_data()); + +#ifdef DEBUG_SHADER + DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string.get_data())); +#endif + + v.frag_id = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(v.frag_id, strings.size(), &strings[0], NULL); + glCompileShader(v.frag_id); + + glGetShaderiv(v.frag_id, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + GLsizei iloglen; + glGetShaderiv(v.frag_id, GL_INFO_LOG_LENGTH, &iloglen); + + if (iloglen < 0) { + glDeleteShader(v.frag_id); + glDeleteShader(v.vert_id); + glDeleteProgram(v.id); + v.id = 0; + + ERR_PRINT("No OpenGL fragment shader compiler log. What the frick?"); + } else { + if (iloglen == 0) { + iloglen = 4096; // buggy driver (Adreno 220+) + } + + char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); + ilogmem[iloglen] = '\0'; + glGetShaderInfoLog(v.frag_id, iloglen, &iloglen, ilogmem); + + String err_string = get_shader_name() + ": Fragment shader compilation failed:\n"; + + err_string += ilogmem; + err_string = _fix_error_code_line(err_string, fragment_code_start, define_line_ofs); + + ERR_PRINTS(err_string); + + Memory::free_static(ilogmem); + glDeleteShader(v.frag_id); + glDeleteShader(v.vert_id); + glDeleteProgram(v.id); + v.id = 0; + } + + ERR_FAIL_V(NULL); + } + + glAttachShader(v.id, v.frag_id); + glAttachShader(v.id, v.vert_id); + + // bind the attribute locations. This has to be done before linking so that the + // linker doesn't assign some random indices + + for (int i = 0; i < attribute_pair_count; i++) { + glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name); + } + + glLinkProgram(v.id); + + glGetProgramiv(v.id, GL_LINK_STATUS, &status); + if (status == GL_FALSE) { + GLsizei iloglen; + glGetProgramiv(v.id, GL_INFO_LOG_LENGTH, &iloglen); + + if (iloglen < 0) { + glDeleteShader(v.frag_id); + glDeleteShader(v.vert_id); + glDeleteProgram(v.id); + v.id = 0; + + ERR_PRINT("No OpenGL program link log. What the frick?"); + ERR_FAIL_V(NULL); + } + + if (iloglen == 0) { + iloglen = 4096; // buggy driver (Adreno 220+) + } + + char *ilogmem = (char *)Memory::alloc_static(iloglen + 1); + ilogmem[iloglen] = '\0'; + glGetProgramInfoLog(v.id, iloglen, &iloglen, ilogmem); + + String err_string = get_shader_name() + ": Program linking failed:\n"; + + err_string += ilogmem; + err_string = _fix_error_code_line(err_string, fragment_code_start, define_line_ofs); + + ERR_PRINTS(err_string); + + Memory::free_static(ilogmem); + glDeleteShader(v.frag_id); + glDeleteShader(v.vert_id); + glDeleteProgram(v.id); + v.id = 0; + + ERR_FAIL_V(NULL); + } + + // get uniform locations + + glUseProgram(v.id); + + for (int i = 0; i < uniform_count; i++) { + v.uniform_location[i] = glGetUniformLocation(v.id, uniform_names[i]); + } + + for (int i = 0; i < texunit_pair_count; i++) { + GLint loc = glGetUniformLocation(v.id, texunit_pairs[i].name); + if (loc >= 0) + glUniform1i(loc, texunit_pairs[i].index); + } + + if (cc) { + v.custom_uniform_locations.resize(cc->custom_uniforms.size()); + for (int i = 0; i < cc->custom_uniforms.size(); i++) { + v.custom_uniform_locations[i] = glGetUniformLocation(v.id, String(cc->custom_uniforms[i]).ascii().get_data()); + } + } + + glUseProgram(0); + v.ok = true; + + return &v; +} + +GLint ShaderGLES2::get_uniform_location(const String &p_name) const { + + ERR_FAIL_COND_V(!version, -1); + return glGetUniformLocation(version->id, p_name.ascii().get_data()); +} + +void ShaderGLES2::setup( + const char **p_conditional_defines, + int p_conditional_count, + const char **p_uniform_names, + int p_uniform_count, + const AttributePair *p_attribute_pairs, + int p_attribute_count, + const TexUnitPair *p_texunit_pairs, + int p_texunit_pair_count, + const char *p_vertex_code, + const char *p_fragment_code, + int p_vertex_code_start, + int p_fragment_code_start) { + + ERR_FAIL_COND(version); + + conditional_version.key = 0; + new_conditional_version.key = 0; + uniform_count = p_uniform_count; + conditional_count = p_conditional_count; + conditional_defines = p_conditional_defines; + uniform_names = p_uniform_names; + vertex_code = p_vertex_code; + fragment_code = p_fragment_code; + texunit_pairs = p_texunit_pairs; + texunit_pair_count = p_texunit_pair_count; + vertex_code_start = p_vertex_code_start; + fragment_code_start = p_fragment_code_start; + attribute_pairs = p_attribute_pairs; + attribute_pair_count = p_attribute_count; + + { + String globals_tag = "\nVERTEX_SHADER_GLOBALS"; + String code_tag = "\nVERTEX_SHADER_CODE"; + String code = vertex_code; + int cpos = code.find(globals_tag); + if (cpos == -1) { + vertex_code0 = code.ascii(); + } else { + vertex_code0 = code.substr(0, cpos).ascii(); + code = code.substr(cpos + globals_tag.length(), code.length()); + + cpos = code.find(code_tag); + + if (cpos == -1) { + vertex_code1 = code.ascii(); + } else { + vertex_code1 = code.substr(0, cpos).ascii(); + vertex_code2 = code.substr(cpos + code_tag.length(), code.length()).ascii(); + } + } + } + + { + String globals_tag = "\nFRAGMENT_SHADER_GLOBALS"; + String code_tag = "\nFRAGMENT_SHADER_CODE"; + String light_code_tag = "\nLIGHT_SHADER_CODE"; + String code = fragment_code; + int cpos = code.find(globals_tag); + if (cpos == -1) { + fragment_code0 = code.ascii(); + } else { + fragment_code0 = code.substr(0, cpos).ascii(); + code = code.substr(cpos + globals_tag.length(), code.length()); + + cpos = code.find(code_tag); + + if (cpos == -1) { + fragment_code1 = code.ascii(); + } else { + + fragment_code1 = code.substr(0, cpos).ascii(); + String code2 = code.substr(cpos + code_tag.length(), code.length()); + + cpos = code2.find(light_code_tag); + if (cpos == -1) { + fragment_code2 = code2.ascii(); + } else { + fragment_code2 = code2.substr(0, cpos).ascii(); + fragment_code3 = code2.substr(cpos + light_code_tag.length(), code2.length()).ascii(); + } + } + } + } +} + +void ShaderGLES2::finish() { + const VersionKey *V = NULL; + + while ((V = version_map.next(V))) { + Version &v = version_map[*V]; + glDeleteShader(v.vert_id); + glDeleteShader(v.frag_id); + glDeleteProgram(v.id); + memdelete_arr(v.uniform_location); + } +} + +void ShaderGLES2::clear_caches() { + const VersionKey *V = NULL; + + while ((V = version_map.next(V))) { + Version &v = version_map[*V]; + glDeleteShader(v.vert_id); + glDeleteShader(v.frag_id); + glDeleteProgram(v.id); + memdelete_arr(v.uniform_location); + } + + version_map.clear(); + + custom_code_map.clear(); + version = NULL; + last_custom_code = 1; + uniforms_dirty = true; +} + +uint32_t ShaderGLES2::create_custom_shader() { + custom_code_map[last_custom_code] = CustomCode(); + custom_code_map[last_custom_code].version = 1; + return last_custom_code++; +} + +void ShaderGLES2::set_custom_shader_code(uint32_t p_code_id, + const String &p_vertex, + const String &p_vertex_globals, + const String &p_fragment, + const String &p_light, + const String &p_fragment_globals, + const Vector<StringName> &p_uniforms, + const Vector<StringName> &p_texture_uniforms, + const Vector<CharString> &p_custom_defines) { + CustomCode *cc = custom_code_map.getptr(p_code_id); + ERR_FAIL_COND(!cc); + + cc->vertex = p_vertex; + cc->vertex_globals = p_vertex_globals; + cc->fragment = p_fragment; + cc->fragment_globals = p_fragment_globals; + cc->light = p_light; + cc->custom_uniforms = p_uniforms; + cc->custom_defines = p_custom_defines; + cc->version++; +} + +void ShaderGLES2::set_custom_shader(uint32_t p_code_id) { + new_conditional_version.code_version = p_code_id; +} + +void ShaderGLES2::free_custom_shader(uint32_t p_code_id) { + ERR_FAIL_COND(!custom_code_map.has(p_code_id)); + if (conditional_version.code_version == p_code_id) + conditional_version.code_version = 0; + + custom_code_map.erase(p_code_id); +} + +void ShaderGLES2::set_base_material_tex_index(int p_idx) { +} + +ShaderGLES2::ShaderGLES2() { + version = NULL; + last_custom_code = 1; + uniforms_dirty = true; +} + +ShaderGLES2::~ShaderGLES2() { + finish(); +} diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h new file mode 100644 index 0000000000..c3635bc201 --- /dev/null +++ b/drivers/gles2/shader_gles2.h @@ -0,0 +1,386 @@ +/*************************************************************************/ +/* shader_gles2.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ +#ifndef SHADER_GLES2_H +#define SHADER_GLES2_H + +#include <stdio.h> + +#include "platform_config.h" +#ifndef GLES2_INCLUDE_H +#include <GLES2/gl2.h> +#else +#include GLES2_INCLUDE_H +#endif + +#include "camera_matrix.h" +#include "hash_map.h" +#include "map.h" +#include "variant.h" + +class ShaderGLES2 { +protected: + struct Enum { + + uint64_t mask; + uint64_t shift; + const char *defines[16]; + }; + + struct EnumValue { + + uint64_t set_mask; + uint64_t clear_mask; + }; + + struct AttributePair { + + const char *name; + int index; + }; + + struct UniformPair { + const char *name; + Variant::Type type_hint; + }; + + struct TexUnitPair { + + const char *name; + int index; + }; + + bool uniforms_dirty; + +private: + //@TODO Optimize to a fixed set of shader pools and use a LRU + int uniform_count; + int texunit_pair_count; + int conditional_count; + int vertex_code_start; + int fragment_code_start; + int attribute_pair_count; + + struct CustomCode { + + String vertex; + String vertex_globals; + String fragment; + String fragment_globals; + String light; + uint32_t version; + Vector<StringName> texture_uniforms; + Vector<StringName> custom_uniforms; + Vector<CharString> custom_defines; + }; + + struct Version { + + GLuint id; + GLuint vert_id; + GLuint frag_id; + GLint *uniform_location; + Vector<GLint> texture_uniform_locations; + Vector<GLint> custom_uniform_locations; + uint32_t code_version; + bool ok; + Version() { + code_version = 0; + ok = false; + uniform_location = NULL; + } + }; + + Version *version; + + union VersionKey { + + struct { + uint32_t version; + uint32_t code_version; + }; + uint64_t key; + bool operator==(const VersionKey &p_key) const { return key == p_key.key; } + bool operator<(const VersionKey &p_key) const { return key < p_key.key; } + }; + + struct VersionKeyHash { + + static _FORCE_INLINE_ uint32_t hash(const VersionKey &p_key) { return HashMapHasherDefault::hash(p_key.key); } + }; + + //this should use a way more cachefriendly version.. + HashMap<VersionKey, Version, VersionKeyHash> version_map; + + HashMap<uint32_t, CustomCode> custom_code_map; + uint32_t last_custom_code; + + VersionKey conditional_version; + VersionKey new_conditional_version; + + virtual String get_shader_name() const = 0; + + const char **conditional_defines; + const char **uniform_names; + const AttributePair *attribute_pairs; + const TexUnitPair *texunit_pairs; + const char *vertex_code; + const char *fragment_code; + CharString fragment_code0; + CharString fragment_code1; + CharString fragment_code2; + CharString fragment_code3; + + CharString vertex_code0; + CharString vertex_code1; + CharString vertex_code2; + + Vector<CharString> custom_defines; + + Version *get_current_version(); + + static ShaderGLES2 *active; + + int max_image_units; + + _FORCE_INLINE_ void _set_uniform_variant(GLint p_uniform, const Variant &p_value) { + + if (p_uniform < 0) + return; // do none + switch (p_value.get_type()) { + + case Variant::BOOL: + case Variant::INT: { + + int val = p_value; + glUniform1i(p_uniform, val); + } break; + case Variant::REAL: { + + real_t val = p_value; + glUniform1f(p_uniform, val); + } break; + case Variant::COLOR: { + + Color val = p_value; + glUniform4f(p_uniform, val.r, val.g, val.b, val.a); + } break; + case Variant::VECTOR2: { + + Vector2 val = p_value; + glUniform2f(p_uniform, val.x, val.y); + } break; + case Variant::VECTOR3: { + + Vector3 val = p_value; + glUniform3f(p_uniform, val.x, val.y, val.z); + } break; + case Variant::PLANE: { + + Plane val = p_value; + glUniform4f(p_uniform, val.normal.x, val.normal.y, val.normal.z, val.d); + } break; + case Variant::QUAT: { + + Quat val = p_value; + glUniform4f(p_uniform, val.x, val.y, val.z, val.w); + } break; + + case Variant::TRANSFORM2D: { + + Transform2D tr = p_value; + GLfloat matrix[16] = { /* build a 16x16 matrix */ + tr.elements[0][0], + tr.elements[0][1], + 0, + 0, + tr.elements[1][0], + tr.elements[1][1], + 0, + 0, + 0, + 0, + 1, + 0, + tr.elements[2][0], + tr.elements[2][1], + 0, + 1 + }; + + glUniformMatrix4fv(p_uniform, 1, false, matrix); + + } break; + case Variant::BASIS: + case Variant::TRANSFORM: { + + Transform tr = p_value; + GLfloat matrix[16] = { /* build a 16x16 matrix */ + tr.basis.elements[0][0], + tr.basis.elements[1][0], + tr.basis.elements[2][0], + 0, + tr.basis.elements[0][1], + tr.basis.elements[1][1], + tr.basis.elements[2][1], + 0, + tr.basis.elements[0][2], + tr.basis.elements[1][2], + tr.basis.elements[2][2], + 0, + tr.origin.x, + tr.origin.y, + tr.origin.z, + 1 + }; + + glUniformMatrix4fv(p_uniform, 1, false, matrix); + } break; + default: { ERR_FAIL(); } // do nothing + } + } + + Map<uint32_t, Variant> uniform_defaults; + Map<uint32_t, CameraMatrix> uniform_cameras; + +protected: + _FORCE_INLINE_ int _get_uniform(int p_which) const; + _FORCE_INLINE_ void _set_conditional(int p_which, bool p_value); + + void setup(const char **p_conditional_defines, + int p_conditional_count, + const char **p_uniform_names, + int p_uniform_count, + const AttributePair *p_attribute_pairs, + int p_attribute_count, + const TexUnitPair *p_texunit_pairs, + int p_texunit_pair_count, + const char *p_vertex_code, + const char *p_fragment_code, + int p_vertex_code_start, + int p_fragment_code_start); + + ShaderGLES2(); + +public: + enum { + CUSTOM_SHADER_DISABLED = 0 + }; + + GLint get_uniform_location(const String &p_name) const; + GLint get_uniform_location(int p_index) const; + + static _FORCE_INLINE_ ShaderGLES2 *get_active() { return active; } + bool bind(); + void unbind(); + void bind_uniforms(); + + inline GLuint get_program() const { return version ? version->id : 0; } + + void clear_caches(); + + uint32_t create_custom_shader(); + void set_custom_shader_code(uint32_t p_code_id, + const String &p_vertex, + const String &p_vertex_globals, + const String &p_fragment, + const String &p_light, + const String &p_fragment_globals, + const Vector<StringName> &p_uniforms, + const Vector<StringName> &p_texture_uniforms, + const Vector<CharString> &p_custom_defines); + + void set_custom_shader(uint32_t p_code_id); + void free_custom_shader(uint32_t p_code_id); + + void set_uniform_default(int p_idx, const Variant &p_value) { + + if (p_value.get_type() == Variant::NIL) { + + uniform_defaults.erase(p_idx); + } else { + + uniform_defaults[p_idx] = p_value; + } + uniforms_dirty = true; + } + + uint32_t get_version() const { return new_conditional_version.version; } + + void set_uniform_camera(int p_idx, const CameraMatrix &p_mat) { + + uniform_cameras[p_idx] = p_mat; + uniforms_dirty = true; + } + + _FORCE_INLINE_ void set_texture_uniform(int p_idx, const Variant &p_value) { + + ERR_FAIL_COND(!version); + ERR_FAIL_INDEX(p_idx, version->texture_uniform_locations.size()); + _set_uniform_variant(version->texture_uniform_locations[p_idx], p_value); + } + + _FORCE_INLINE_ GLint get_texture_uniform_location(int p_idx) { + + ERR_FAIL_COND_V(!version, -1); + ERR_FAIL_INDEX_V(p_idx, version->texture_uniform_locations.size(), -1); + return version->texture_uniform_locations[p_idx]; + } + + virtual void init() = 0; + void finish(); + + void set_base_material_tex_index(int p_idx); + + void add_custom_define(const String &p_define) { + custom_defines.push_back(p_define.utf8()); + } + + virtual ~ShaderGLES2(); +}; + +// called a lot, made inline + +int ShaderGLES2::_get_uniform(int p_which) const { + + ERR_FAIL_INDEX_V(p_which, uniform_count, -1); + ERR_FAIL_COND_V(!version, -1); + return version->uniform_location[p_which]; +} + +void ShaderGLES2::_set_conditional(int p_which, bool p_value) { + + ERR_FAIL_INDEX(p_which, conditional_count); + if (p_value) + new_conditional_version.version |= (1 << p_which); + else + new_conditional_version.version &= ~(1 << p_which); +} + +#endif diff --git a/drivers/gles2/shaders/SCsub b/drivers/gles2/shaders/SCsub new file mode 100644 index 0000000000..5de3e1ac90 --- /dev/null +++ b/drivers/gles2/shaders/SCsub @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +Import('env') + +if 'GLES2_GLSL' in env['BUILDERS']: + env.GLES2_GLSL('copy.glsl'); +# env.GLES2_GLSL('resolve.glsl'); + env.GLES2_GLSL('canvas.glsl'); +# env.GLES2_GLSL('canvas_shadow.glsl'); + env.GLES2_GLSL('scene.glsl'); +# env.GLES2_GLSL('cubemap_filter.glsl'); +# env.GLES2_GLSL('cube_to_dp.glsl'); +# env.GLES2_GLSL('blend_shape.glsl'); +# env.GLES2_GLSL('screen_space_reflection.glsl'); +# env.GLES2_GLSL('effect_blur.glsl'); +# env.GLES2_GLSL('subsurf_scattering.glsl'); +# env.GLES2_GLSL('ssao.glsl'); +# env.GLES2_GLSL('ssao_minify.glsl'); +# env.GLES2_GLSL('ssao_blur.glsl'); +# env.GLES2_GLSL('exposure.glsl'); +# env.GLES2_GLSL('tonemap.glsl'); +# env.GLES2_GLSL('particles.glsl'); diff --git a/drivers/gles2/shaders/blend_shape.glsl b/drivers/gles2/shaders/blend_shape.glsl new file mode 100644 index 0000000000..4e0d066823 --- /dev/null +++ b/drivers/gles2/shaders/blend_shape.glsl @@ -0,0 +1,197 @@ +[vertex] + + +/* +from VisualServer: + +ARRAY_VERTEX=0, +ARRAY_NORMAL=1, +ARRAY_TANGENT=2, +ARRAY_COLOR=3, +ARRAY_TEX_UV=4, +ARRAY_TEX_UV2=5, +ARRAY_BONES=6, +ARRAY_WEIGHTS=7, +ARRAY_INDEX=8, +*/ + +#ifdef USE_2D_VERTEX +#define VFORMAT vec2 +#else +#define VFORMAT vec3 +#endif + +/* INPUT ATTRIBS */ + +layout(location=0) in highp VFORMAT vertex_attrib; +layout(location=1) in vec3 normal_attrib; + +#ifdef ENABLE_TANGENT +layout(location=2) in vec4 tangent_attrib; +#endif + +#ifdef ENABLE_COLOR +layout(location=3) in vec4 color_attrib; +#endif + +#ifdef ENABLE_UV +layout(location=4) in vec2 uv_attrib; +#endif + +#ifdef ENABLE_UV2 +layout(location=5) in vec2 uv2_attrib; +#endif + +#ifdef ENABLE_SKELETON +layout(location=6) in ivec4 bone_attrib; +layout(location=7) in vec4 weight_attrib; +#endif + +/* BLEND ATTRIBS */ + +#ifdef ENABLE_BLEND + +layout(location=8) in highp VFORMAT vertex_attrib_blend; +layout(location=9) in vec3 normal_attrib_blend; + +#ifdef ENABLE_TANGENT +layout(location=10) in vec4 tangent_attrib_blend; +#endif + +#ifdef ENABLE_COLOR +layout(location=11) in vec4 color_attrib_blend; +#endif + +#ifdef ENABLE_UV +layout(location=12) in vec2 uv_attrib_blend; +#endif + +#ifdef ENABLE_UV2 +layout(location=13) in vec2 uv2_attrib_blend; +#endif + +#ifdef ENABLE_SKELETON +layout(location=14) in ivec4 bone_attrib_blend; +layout(location=15) in vec4 weight_attrib_blend; +#endif + +#endif + +/* OUTPUTS */ + +out VFORMAT vertex_out; //tfb: + +#ifdef ENABLE_NORMAL +out vec3 normal_out; //tfb:ENABLE_NORMAL +#endif + +#ifdef ENABLE_TANGENT +out vec4 tangent_out; //tfb:ENABLE_TANGENT +#endif + +#ifdef ENABLE_COLOR +out vec4 color_out; //tfb:ENABLE_COLOR +#endif + +#ifdef ENABLE_UV +out vec2 uv_out; //tfb:ENABLE_UV +#endif + +#ifdef ENABLE_UV2 +out vec2 uv2_out; //tfb:ENABLE_UV2 +#endif + +#ifdef ENABLE_SKELETON +out ivec4 bone_out; //tfb:ENABLE_SKELETON +out vec4 weight_out; //tfb:ENABLE_SKELETON +#endif + +uniform float blend_amount; + +void main() { + + +#ifdef ENABLE_BLEND + + vertex_out = vertex_attrib_blend + vertex_attrib * blend_amount; + +#ifdef ENABLE_NORMAL + normal_out = normal_attrib_blend + normal_attrib * blend_amount; +#endif + +#ifdef ENABLE_TANGENT + + tangent_out.xyz = tangent_attrib_blend.xyz + tangent_attrib.xyz * blend_amount; + tangent_out.w = tangent_attrib_blend.w; //just copy, no point in blending his +#endif + +#ifdef ENABLE_COLOR + + color_out = color_attrib_blend + color_attrib * blend_amount; +#endif + +#ifdef ENABLE_UV + + uv_out = uv_attrib_blend + uv_attrib * blend_amount; +#endif + +#ifdef ENABLE_UV2 + + uv2_out = uv2_attrib_blend + uv2_attrib * blend_amount; +#endif + + +#ifdef ENABLE_SKELETON + + bone_out = bone_attrib_blend; + weight_out = weight_attrib_blend + weight_attrib * blend_amount; +#endif + +#else //ENABLE_BLEND + + + vertex_out = vertex_attrib * blend_amount; + +#ifdef ENABLE_NORMAL + normal_out = normal_attrib * blend_amount; +#endif + +#ifdef ENABLE_TANGENT + + tangent_out.xyz = tangent_attrib.xyz * blend_amount; + tangent_out.w = tangent_attrib.w; //just copy, no point in blending his +#endif + +#ifdef ENABLE_COLOR + + color_out = color_attrib * blend_amount; +#endif + +#ifdef ENABLE_UV + + uv_out = uv_attrib * blend_amount; +#endif + +#ifdef ENABLE_UV2 + + uv2_out = uv2_attrib * blend_amount; +#endif + + +#ifdef ENABLE_SKELETON + + bone_out = bone_attrib; + weight_out = weight_attrib * blend_amount; +#endif + +#endif + gl_Position = vec4(0.0); +} + +[fragment] + + +void main() { + +} + diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl new file mode 100644 index 0000000000..11c6ab9b76 --- /dev/null +++ b/drivers/gles2/shaders/canvas.glsl @@ -0,0 +1,141 @@ +[vertex] + +#ifdef USE_GLES_OVER_GL +#define mediump +#define highp +#else +precision mediump float; +precision mediump int; +#endif + +uniform highp mat4 projection_matrix; +uniform highp mat4 modelview_matrix; +uniform highp mat4 extra_matrix; +attribute highp vec2 vertex; // attrib:0 +attribute vec4 color_attrib; // attrib:3 +attribute vec2 uv_attrib; // attrib:4 + +varying vec2 uv_interp; +varying vec4 color_interp; + +uniform highp vec2 color_texpixel_size; + +#ifdef USE_TEXTURE_RECT + +uniform vec4 dst_rect; +uniform vec4 src_rect; + +#endif + +uniform bool blit_pass; + +VERTEX_SHADER_GLOBALS + +vec2 select(vec2 a, vec2 b, bvec2 c) { + vec2 ret; + + ret.x = c.x ? b.x : a.x; + ret.y = c.y ? b.y : a.y; + + return ret; +} + +void main() { + + vec4 color = color_attrib; + +#ifdef USE_TEXTURE_RECT + + if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z + uv_interp = src_rect.xy + abs(src_rect.zw) * vertex.yx; + } else { + uv_interp = src_rect.xy + abs(src_rect.zw) * vertex; + } + + vec4 outvec = vec4(0.0, 0.0, 0.0, 1.0); + + // This is what is done in the GLES 3 bindings and should + // take care of flipped rects. + // + // But it doesn't. + // I don't know why, will need to investigate further. + + outvec.xy = dst_rect.xy + abs(dst_rect.zw) * select(vertex, vec2(1.0, 1.0) - vertex, lessThan(src_rect.zw, vec2(0.0, 0.0))); + + // outvec.xy = dst_rect.xy + abs(dst_rect.zw) * vertex; +#else + vec4 outvec = vec4(vertex.xy, 0.0, 1.0); + +#ifdef USE_UV_ATTRIBUTE + uv_interp = uv_attrib; +#else + uv_interp = vertex.xy; +#endif + +#endif + +{ + vec2 src_vtx=outvec.xy; +VERTEX_SHADER_CODE + +} + + color_interp = color; + + gl_Position = projection_matrix * modelview_matrix * outvec; + +} + +[fragment] + +#ifdef USE_GLES_OVER_GL +#define mediump +#define highp +#else +precision mediump float; +precision mediump int; +#endif + +uniform sampler2D color_texture; // texunit:0 +uniform highp vec2 color_texpixel_size; +uniform mediump sampler2D normal_texture; // texunit:1 + +varying mediump vec2 uv_interp; +varying mediump vec4 color_interp; + +uniform bool blit_pass; + +uniform vec4 final_modulate; + +#ifdef SCREEN_TEXTURE_USED + +uniform sampler2D screen_texture; // texunit:2 + +#endif + +#ifdef SCREEN_UV_USED + +uniform vec2 screen_pixel_size; + +#endif + +FRAGMENT_SHADER_GLOBALS + + +void main() { + + vec4 color = color_interp; + + color *= texture2D(color_texture, uv_interp); +{ + +FRAGMENT_SHADER_CODE + + +} + + color *= final_modulate; + + gl_FragColor = color; + +} diff --git a/drivers/gles2/shaders/canvas_shadow.glsl b/drivers/gles2/shaders/canvas_shadow.glsl new file mode 100644 index 0000000000..c757990de0 --- /dev/null +++ b/drivers/gles2/shaders/canvas_shadow.glsl @@ -0,0 +1,49 @@ +[vertex] + + + +uniform highp mat4 projection_matrix; +uniform highp mat4 light_matrix; +uniform highp mat4 world_matrix; +uniform highp float distance_norm; + +layout(location=0) in highp vec3 vertex; + +out highp vec4 position_interp; + +void main() { + + gl_Position = projection_matrix * (light_matrix * (world_matrix * vec4(vertex,1.0))); + position_interp=gl_Position; +} + +[fragment] + +in highp vec4 position_interp; + +#ifdef USE_RGBA_SHADOWS + +layout(location=0) out lowp vec4 distance_buf; + +#else + +layout(location=0) out highp float distance_buf; + +#endif + +void main() { + + highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0;//bias; + +#ifdef USE_RGBA_SHADOWS + + highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0)); + comp -= comp.xxyz * vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); + distance_buf=comp; +#else + + distance_buf=depth; + +#endif +} + diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl new file mode 100644 index 0000000000..a21da68525 --- /dev/null +++ b/drivers/gles2/shaders/copy.glsl @@ -0,0 +1,72 @@ +[vertex] + +#ifdef USE_GLES_OVER_GL +#define mediump +#define highp +#else +precision mediump float; +precision mediump int; +#endif + +attribute highp vec4 vertex_attrib; // attrib:0 +attribute vec2 uv_in; // attrib:4 +attribute vec2 uv2_in; // attrib:5 + +varying vec2 uv_interp; + +varying vec2 uv2_interp; + +#ifdef USE_COPY_SECTION +uniform vec4 copy_section; +#endif + +void main() { + + uv_interp = uv_in; + uv2_interp = uv2_in; + gl_Position = vertex_attrib; + +#ifdef USE_COPY_SECTION + uv_interp = copy_section.xy + uv_interp * copy_section.zw; + gl_Position.xy = (copy_section.xy + (gl_Position.xy * 0.5 + 0.5) * copy_section.zw) * 2.0 - 1.0; +#endif +} + +[fragment] + +#ifdef USE_GLES_OVER_GL +#define mediump +#define highp +#else +precision mediump float; +precision mediump int; +#endif + + +varying vec2 uv_interp; +uniform sampler2D source; // texunit:0 + +varying vec2 uv2_interp; + +#ifdef USE_CUSTOM_ALPHA +uniform float custom_alpha; +#endif + + +void main() { + + //vec4 color = color_interp; + vec4 color = texture2D( source, uv_interp ); + + +#ifdef USE_NO_ALPHA + color.a=1.0; +#endif + +#ifdef USE_CUSTOM_ALPHA + color.a=custom_alpha; +#endif + + + gl_FragColor = color; +} diff --git a/drivers/gles2/shaders/cube_to_dp.glsl b/drivers/gles2/shaders/cube_to_dp.glsl new file mode 100644 index 0000000000..5ffc78c0b9 --- /dev/null +++ b/drivers/gles2/shaders/cube_to_dp.glsl @@ -0,0 +1,79 @@ +[vertex] + + +layout(location=0) in highp vec4 vertex_attrib; +layout(location=4) in vec2 uv_in; + +out vec2 uv_interp; + +void main() { + + uv_interp = uv_in; + gl_Position = vertex_attrib; +} + +[fragment] + + +uniform highp samplerCube source_cube; //texunit:0 +in vec2 uv_interp; + +uniform bool z_flip; +uniform highp float z_far; +uniform highp float z_near; +uniform highp float bias; + +void main() { + + highp vec3 normal = vec3( uv_interp * 2.0 - 1.0, 0.0 ); +/* + if(z_flip) { + normal.z = 0.5 - 0.5*((normal.x * normal.x) + (normal.y * normal.y)); + } else { + normal.z = -0.5 + 0.5*((normal.x * normal.x) + (normal.y * normal.y)); + } +*/ + + //normal.z = sqrt(1.0-dot(normal.xy,normal.xy)); + //normal.xy*=1.0+normal.z; + + normal.z = 0.5 - 0.5*((normal.x * normal.x) + (normal.y * normal.y)); + normal = normalize(normal); + +/* + normal.z=0.5; + normal=normalize(normal); +*/ + if (!z_flip) { + normal.z=-normal.z; + } + + //normal = normalize(vec3( uv_interp * 2.0 - 1.0, 1.0 )); + float depth = texture(source_cube,normal).r; + + // absolute values for direction cosines, bigger value equals closer to basis axis + vec3 unorm = abs(normal); + + if ( (unorm.x >= unorm.y) && (unorm.x >= unorm.z) ) { + // x code + unorm = normal.x > 0.0 ? vec3( 1.0, 0.0, 0.0 ) : vec3( -1.0, 0.0, 0.0 ) ; + } else if ( (unorm.y > unorm.x) && (unorm.y >= unorm.z) ) { + // y code + unorm = normal.y > 0.0 ? vec3( 0.0, 1.0, 0.0 ) : vec3( 0.0, -1.0, 0.0 ) ; + } else if ( (unorm.z > unorm.x) && (unorm.z > unorm.y) ) { + // z code + unorm = normal.z > 0.0 ? vec3( 0.0, 0.0, 1.0 ) : vec3( 0.0, 0.0, -1.0 ) ; + } else { + // oh-no we messed up code + // has to be + unorm = vec3( 1.0, 0.0, 0.0 ); + } + + float depth_fix = 1.0 / dot(normal,unorm); + + + depth = 2.0 * depth - 1.0; + float linear_depth = 2.0 * z_near * z_far / (z_far + z_near - depth * (z_far - z_near)); + gl_FragDepth = (linear_depth*depth_fix+bias) / z_far; +} + diff --git a/drivers/gles2/shaders/cubemap_filter.glsl b/drivers/gles2/shaders/cubemap_filter.glsl new file mode 100644 index 0000000000..485fbb6ee0 --- /dev/null +++ b/drivers/gles2/shaders/cubemap_filter.glsl @@ -0,0 +1,294 @@ +[vertex] + + +layout(location=0) in highp vec2 vertex; + +layout(location=4) in highp vec2 uv; + +out highp vec2 uv_interp; + +void main() { + + uv_interp=uv; + gl_Position=vec4(vertex,0,1); +} + +[fragment] + + +precision highp float; +precision highp int; + +#ifdef USE_SOURCE_PANORAMA +uniform sampler2D source_panorama; //texunit:0 +#endif + +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY +uniform sampler2DArray source_dual_paraboloid_array; //texunit:0 +uniform int source_array_index; +#endif + +#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) +uniform samplerCube source_cube; //texunit:0 +#endif + +uniform int face_id; +uniform float roughness; +in highp vec2 uv_interp; + + +layout(location = 0) out vec4 frag_color; + + +#define M_PI 3.14159265359 + + +vec3 texelCoordToVec(vec2 uv, int faceID) +{ + mat3 faceUvVectors[6]; +/* + // -x + faceUvVectors[1][0] = vec3(0.0, 0.0, 1.0); // u -> +z + faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[1][2] = vec3(-1.0, 0.0, 0.0); // -x face + + // +x + faceUvVectors[0][0] = vec3(0.0, 0.0, -1.0); // u -> -z + faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[0][2] = vec3(1.0, 0.0, 0.0); // +x face + + // -y + faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[3][1] = vec3(0.0, 0.0, -1.0); // v -> -z + faceUvVectors[3][2] = vec3(0.0, -1.0, 0.0); // -y face + + // +y + faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[2][1] = vec3(0.0, 0.0, 1.0); // v -> +z + faceUvVectors[2][2] = vec3(0.0, 1.0, 0.0); // +y face + + // -z + faceUvVectors[5][0] = vec3(-1.0, 0.0, 0.0); // u -> -x + faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[5][2] = vec3(0.0, 0.0, -1.0); // -z face + + // +z + faceUvVectors[4][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[4][2] = vec3(0.0, 0.0, 1.0); // +z face +*/ + + // -x + faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z + faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face + + // +x + faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z + faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face + + // -y + faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z + faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face + + // +y + faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0); // v -> +z + faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0); // +y face + + // -z + faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x + faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face + + // +z + faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x + faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y + faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face + + // out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2]. + vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2]; + return normalize(result); +} + +vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) +{ + float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph] + + // Compute distribution direction + float Phi = 2.0 * M_PI * Xi.x; + float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); + float SinTheta = sqrt(1.0 - CosTheta * CosTheta); + + // Convert to spherical direction + vec3 H; + H.x = SinTheta * cos(Phi); + H.y = SinTheta * sin(Phi); + H.z = CosTheta; + + vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + vec3 TangentX = normalize(cross(UpVector, N)); + vec3 TangentY = cross(N, TangentX); + + // Tangent to world space + return TangentX * H.x + TangentY * H.y + N * H.z; +} + +// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html +float GGX(float NdotV, float a) +{ + float k = a / 2.0; + return NdotV / (NdotV * (1.0 - k) + k); +} + +// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html +float G_Smith(float a, float nDotV, float nDotL) +{ + return GGX(nDotL, a * a) * GGX(nDotV, a * a); +} + +float radicalInverse_VdC(uint bits) { + bits = (bits << 16u) | (bits >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + return float(bits) * 2.3283064365386963e-10; // / 0x100000000 +} + +vec2 Hammersley(uint i, uint N) { + return vec2(float(i)/float(N), radicalInverse_VdC(i)); +} + + + +#ifdef LOW_QUALITY + +#define SAMPLE_COUNT 64u + +#else + +#define SAMPLE_COUNT 512u + +#endif + +uniform bool z_flip; + +#ifdef USE_SOURCE_PANORAMA + +vec4 texturePanorama(vec3 normal,sampler2D pano ) { + + vec2 st = vec2( + atan(normal.x, normal.z), + acos(normal.y) + ); + + if(st.x < 0.0) + st.x += M_PI*2.0; + + st/=vec2(M_PI*2.0,M_PI); + + return textureLod(pano,st,0.0); + +} + +#endif + +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY + + +vec4 textureDualParaboloidArray(vec3 normal) { + + vec3 norm = normalize(normal); + norm.xy/=1.0+abs(norm.z); + norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); + if (norm.z<0.0) { + norm.y=0.5-norm.y+0.5; + } + return textureLod(source_dual_paraboloid_array, vec3(norm.xy, float(source_array_index) ), 0.0); + +} + +#endif + +void main() { + +#ifdef USE_DUAL_PARABOLOID + + vec3 N = vec3( uv_interp * 2.0 - 1.0, 0.0 ); + N.z = 0.5 - 0.5*((N.x * N.x) + (N.y * N.y)); + N = normalize(N); + + if (z_flip) { + N.y=-N.y; //y is flipped to improve blending between both sides + N.z=-N.z; + } + + +#else + vec2 uv = (uv_interp * 2.0) - 1.0; + vec3 N = texelCoordToVec(uv, face_id); +#endif + //vec4 color = color_interp; + +#ifdef USE_DIRECT_WRITE + +#ifdef USE_SOURCE_PANORAMA + + frag_color=vec4(texturePanorama(N,source_panorama).rgb,1.0); +#endif + +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY + + frag_color=vec4(textureDualParaboloidArray(N).rgb,1.0); +#endif + +#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) + + N.y=-N.y; + frag_color=vec4(texture(N,source_cube).rgb,1.0); +#endif + + + + +#else + + vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); + + for(uint sampleNum = 0u; sampleNum < SAMPLE_COUNT; sampleNum++) { + vec2 xi = Hammersley(sampleNum, SAMPLE_COUNT); + + vec3 H = ImportanceSampleGGX( xi, roughness, N ); + vec3 V = N; + vec3 L = normalize(2.0 * dot( V, H ) * H - V); + + float ndotl = clamp(dot(N, L),0.0,1.0); + + if (ndotl>0.0) { +#ifdef USE_SOURCE_PANORAMA + sum.rgb += texturePanorama(H,source_panorama).rgb *ndotl; +#endif + +#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY + + sum.rgb += textureDualParaboloidArray(H).rgb *ndotl; +#endif + +#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) + H.y=-H.y; + sum.rgb += textureLod(source_cube, H, 0.0).rgb *ndotl; +#endif + sum.a += ndotl; + } + } + sum /= sum.a; + + frag_color = vec4(sum.rgb, 1.0); + +#endif + +} + diff --git a/drivers/gles2/shaders/effect_blur.glsl b/drivers/gles2/shaders/effect_blur.glsl new file mode 100644 index 0000000000..b5f98a1244 --- /dev/null +++ b/drivers/gles2/shaders/effect_blur.glsl @@ -0,0 +1,301 @@ +[vertex] + + +layout(location=0) in highp vec4 vertex_attrib; +layout(location=4) in vec2 uv_in; + +out vec2 uv_interp; + +#ifdef USE_BLUR_SECTION + +uniform vec4 blur_section; + +#endif + +void main() { + + uv_interp = uv_in; + gl_Position = vertex_attrib; +#ifdef USE_BLUR_SECTION + + uv_interp = blur_section.xy + uv_interp * blur_section.zw; + gl_Position.xy = (blur_section.xy + (gl_Position.xy * 0.5 + 0.5) * blur_section.zw) * 2.0 - 1.0; +#endif +} + +[fragment] + +#if !defined(GLES_OVER_GL) +precision mediump float; +#endif + +in vec2 uv_interp; +uniform sampler2D source_color; //texunit:0 + +#ifdef SSAO_MERGE +uniform sampler2D source_ssao; //texunit:1 +#endif + +uniform float lod; +uniform vec2 pixel_size; + + +layout(location = 0) out vec4 frag_color; + +#ifdef SSAO_MERGE + +uniform vec4 ssao_color; + +#endif + +#if defined (GLOW_GAUSSIAN_HORIZONTAL) || defined(GLOW_GAUSSIAN_VERTICAL) + +uniform float glow_strength; + +#endif + +#if defined(DOF_FAR_BLUR) || defined (DOF_NEAR_BLUR) + +#ifdef DOF_QUALITY_LOW +const int dof_kernel_size=5; +const int dof_kernel_from=2; +const float dof_kernel[5] = float[] (0.153388,0.221461,0.250301,0.221461,0.153388); +#endif + +#ifdef DOF_QUALITY_MEDIUM +const int dof_kernel_size=11; +const int dof_kernel_from=5; +const float dof_kernel[11] = float[] (0.055037,0.072806,0.090506,0.105726,0.116061,0.119726,0.116061,0.105726,0.090506,0.072806,0.055037); + +#endif + +#ifdef DOF_QUALITY_HIGH +const int dof_kernel_size=21; +const int dof_kernel_from=10; +const float dof_kernel[21] = float[] (0.028174,0.032676,0.037311,0.041944,0.046421,0.050582,0.054261,0.057307,0.059587,0.060998,0.061476,0.060998,0.059587,0.057307,0.054261,0.050582,0.046421,0.041944,0.037311,0.032676,0.028174); +#endif + +uniform sampler2D dof_source_depth; //texunit:1 +uniform float dof_begin; +uniform float dof_end; +uniform vec2 dof_dir; +uniform float dof_radius; + +#ifdef DOF_NEAR_BLUR_MERGE + +uniform sampler2D source_dof_original; //texunit:2 +#endif + +#endif + + +#ifdef GLOW_FIRST_PASS + +uniform float exposure; +uniform float white; + +#ifdef GLOW_USE_AUTO_EXPOSURE + +uniform highp sampler2D source_auto_exposure; //texunit:1 +uniform highp float auto_exposure_grey; + +#endif + +uniform float glow_bloom; +uniform float glow_hdr_threshold; +uniform float glow_hdr_scale; + +#endif + +uniform float camera_z_far; +uniform float camera_z_near; + +void main() { + + + +#ifdef GAUSSIAN_HORIZONTAL + vec2 pix_size = pixel_size; + pix_size*=0.5; //reading from larger buffer, so use more samples + vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pix_size,lod )*0.214607; + color+=textureLod( source_color, uv_interp+vec2( 1.0, 0.0)*pix_size,lod )*0.189879; + color+=textureLod( source_color, uv_interp+vec2( 2.0, 0.0)*pix_size,lod )*0.157305; + color+=textureLod( source_color, uv_interp+vec2( 3.0, 0.0)*pix_size,lod )*0.071303; + color+=textureLod( source_color, uv_interp+vec2(-1.0, 0.0)*pix_size,lod )*0.189879; + color+=textureLod( source_color, uv_interp+vec2(-2.0, 0.0)*pix_size,lod )*0.157305; + color+=textureLod( source_color, uv_interp+vec2(-3.0, 0.0)*pix_size,lod )*0.071303; + frag_color = color; +#endif + +#ifdef GAUSSIAN_VERTICAL + vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pixel_size,lod )*0.38774; + color+=textureLod( source_color, uv_interp+vec2( 0.0, 1.0)*pixel_size,lod )*0.24477; + color+=textureLod( source_color, uv_interp+vec2( 0.0, 2.0)*pixel_size,lod )*0.06136; + color+=textureLod( source_color, uv_interp+vec2( 0.0,-1.0)*pixel_size,lod )*0.24477; + color+=textureLod( source_color, uv_interp+vec2( 0.0,-2.0)*pixel_size,lod )*0.06136; + frag_color = color; +#endif + +//glow uses larger sigma for a more rounded blur effect + +#ifdef GLOW_GAUSSIAN_HORIZONTAL + vec2 pix_size = pixel_size; + pix_size*=0.5; //reading from larger buffer, so use more samples + vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pix_size,lod )*0.174938; + color+=textureLod( source_color, uv_interp+vec2( 1.0, 0.0)*pix_size,lod )*0.165569; + color+=textureLod( source_color, uv_interp+vec2( 2.0, 0.0)*pix_size,lod )*0.140367; + color+=textureLod( source_color, uv_interp+vec2( 3.0, 0.0)*pix_size,lod )*0.106595; + color+=textureLod( source_color, uv_interp+vec2(-1.0, 0.0)*pix_size,lod )*0.165569; + color+=textureLod( source_color, uv_interp+vec2(-2.0, 0.0)*pix_size,lod )*0.140367; + color+=textureLod( source_color, uv_interp+vec2(-3.0, 0.0)*pix_size,lod )*0.106595; + color*=glow_strength; + frag_color = color; +#endif + +#ifdef GLOW_GAUSSIAN_VERTICAL + vec4 color =textureLod( source_color, uv_interp+vec2(0.0, 0.0)*pixel_size,lod )*0.288713; + color+=textureLod( source_color, uv_interp+vec2(0.0, 1.0)*pixel_size,lod )*0.233062; + color+=textureLod( source_color, uv_interp+vec2(0.0, 2.0)*pixel_size,lod )*0.122581; + color+=textureLod( source_color, uv_interp+vec2(0.0,-1.0)*pixel_size,lod )*0.233062; + color+=textureLod( source_color, uv_interp+vec2(0.0,-2.0)*pixel_size,lod )*0.122581; + color*=glow_strength; + frag_color = color; +#endif + +#ifdef DOF_FAR_BLUR + + vec4 color_accum = vec4(0.0); + + float depth = textureLod( dof_source_depth, uv_interp, 0.0).r; + depth = depth * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else + depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); +#endif + + float amount = smoothstep(dof_begin,dof_end,depth); + float k_accum=0.0; + + for(int i=0;i<dof_kernel_size;i++) { + + int int_ofs = i-dof_kernel_from; + vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * amount * dof_radius; + + float tap_k = dof_kernel[i]; + + float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r; + tap_depth = tap_depth * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + tap_depth = ((tap_depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else + tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near)); +#endif + float tap_amount = mix(smoothstep(dof_begin,dof_end,tap_depth),1.0,int_ofs==0); + tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect + + vec4 tap_color = textureLod( source_color, tap_uv, 0.0) * tap_k; + + k_accum+=tap_k*tap_amount; + color_accum+=tap_color*tap_amount; + + + } + + if (k_accum>0.0) { + color_accum/=k_accum; + } + + frag_color = color_accum;///k_accum; + +#endif + +#ifdef DOF_NEAR_BLUR + + vec4 color_accum = vec4(0.0); + + float max_accum=0; + + for(int i=0;i<dof_kernel_size;i++) { + + int int_ofs = i-dof_kernel_from; + vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * dof_radius; + float ofs_influence = max(0.0,1.0-float(abs(int_ofs))/float(dof_kernel_from)); + + float tap_k = dof_kernel[i]; + + vec4 tap_color = textureLod( source_color, tap_uv, 0.0); + + float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r; + tap_depth = tap_depth * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + tap_depth = ((tap_depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else + tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near)); +#endif + float tap_amount = 1.0-smoothstep(dof_end,dof_begin,tap_depth); + tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect + +#ifdef DOF_NEAR_FIRST_TAP + + tap_color.a= 1.0-smoothstep(dof_end,dof_begin,tap_depth); + +#endif + + max_accum=max(max_accum,tap_amount*ofs_influence); + + color_accum+=tap_color*tap_k; + + } + + color_accum.a=max(color_accum.a,sqrt(max_accum)); + + +#ifdef DOF_NEAR_BLUR_MERGE + + vec4 original = textureLod( source_dof_original, uv_interp, 0.0); + color_accum = mix(original,color_accum,color_accum.a); + +#endif + +#ifndef DOF_NEAR_FIRST_TAP + //color_accum=vec4(vec3(color_accum.a),1.0); +#endif + frag_color = color_accum; + +#endif + + + +#ifdef GLOW_FIRST_PASS + +#ifdef GLOW_USE_AUTO_EXPOSURE + + frag_color/=texelFetch(source_auto_exposure,ivec2(0,0),0).r/auto_exposure_grey; +#endif + frag_color*=exposure; + + float luminance = max(frag_color.r,max(frag_color.g,frag_color.b)); + float feedback = max( smoothstep(glow_hdr_threshold,glow_hdr_threshold+glow_hdr_scale,luminance), glow_bloom ); + + frag_color *= feedback; + +#endif + + +#ifdef SIMPLE_COPY + vec4 color =textureLod( source_color, uv_interp,0.0); + frag_color = color; +#endif + +#ifdef SSAO_MERGE + + vec4 color =textureLod( source_color, uv_interp,0.0); + float ssao =textureLod( source_ssao, uv_interp,0.0).r; + + frag_color = vec4( mix(color.rgb,color.rgb*mix(ssao_color.rgb,vec3(1.0),ssao),color.a), 1.0 ); + +#endif + + +} diff --git a/drivers/gles2/shaders/exposure.glsl b/drivers/gles2/shaders/exposure.glsl new file mode 100644 index 0000000000..001b90a0f1 --- /dev/null +++ b/drivers/gles2/shaders/exposure.glsl @@ -0,0 +1,98 @@ +[vertex] + + +layout(location=0) in highp vec4 vertex_attrib; + + +void main() { + + gl_Position = vertex_attrib; + +} + +[fragment] + + +uniform highp sampler2D source_exposure; //texunit:0 + +#ifdef EXPOSURE_BEGIN + +uniform highp ivec2 source_render_size; +uniform highp ivec2 target_size; + +#endif + +#ifdef EXPOSURE_END + +uniform highp sampler2D prev_exposure; //texunit:1 +uniform highp float exposure_adjust; +uniform highp float min_luminance; +uniform highp float max_luminance; + +#endif + +layout(location = 0) out highp float exposure; + + + +void main() { + + + +#ifdef EXPOSURE_BEGIN + + + ivec2 src_pos = ivec2(gl_FragCoord.xy)*source_render_size/target_size; + +#if 1 + //more precise and expensive, but less jittery + ivec2 next_pos = ivec2(gl_FragCoord.xy+ivec2(1))*source_render_size/target_size; + next_pos = max(next_pos,src_pos+ivec2(1)); //so it at least reads one pixel + highp vec3 source_color=vec3(0.0); + for(int i=src_pos.x;i<next_pos.x;i++) { + for(int j=src_pos.y;j<next_pos.y;j++) { + source_color += texelFetch(source_exposure,ivec2(i,j),0).rgb; + } + } + + source_color/=float( (next_pos.x-src_pos.x)*(next_pos.y-src_pos.y) ); +#else + highp vec3 source_color = texelFetch(source_exposure,src_pos,0).rgb; + +#endif + + exposure = max(source_color.r,max(source_color.g,source_color.b)); + +#else + + ivec2 coord = ivec2(gl_FragCoord.xy); + exposure = texelFetch(source_exposure,coord*3+ivec2(0,0),0).r; + exposure += texelFetch(source_exposure,coord*3+ivec2(1,0),0).r; + exposure += texelFetch(source_exposure,coord*3+ivec2(2,0),0).r; + exposure += texelFetch(source_exposure,coord*3+ivec2(0,1),0).r; + exposure += texelFetch(source_exposure,coord*3+ivec2(1,1),0).r; + exposure += texelFetch(source_exposure,coord*3+ivec2(2,1),0).r; + exposure += texelFetch(source_exposure,coord*3+ivec2(0,2),0).r; + exposure += texelFetch(source_exposure,coord*3+ivec2(1,2),0).r; + exposure += texelFetch(source_exposure,coord*3+ivec2(2,2),0).r; + exposure *= (1.0/9.0); + +#ifdef EXPOSURE_END + +#ifdef EXPOSURE_FORCE_SET + //will stay as is +#else + highp float prev_lum = texelFetch(prev_exposure,ivec2(0,0),0).r; //1 pixel previous exposure + exposure = clamp( prev_lum + (exposure-prev_lum)*exposure_adjust,min_luminance,max_luminance); + +#endif //EXPOSURE_FORCE_SET + + +#endif //EXPOSURE_END + +#endif //EXPOSURE_BEGIN + + +} + + diff --git a/drivers/gles2/shaders/particles.glsl b/drivers/gles2/shaders/particles.glsl new file mode 100644 index 0000000000..a62c124dfe --- /dev/null +++ b/drivers/gles2/shaders/particles.glsl @@ -0,0 +1,260 @@ +[vertex] + + + +layout(location=0) in highp vec4 color; +layout(location=1) in highp vec4 velocity_active; +layout(location=2) in highp vec4 custom; +layout(location=3) in highp vec4 xform_1; +layout(location=4) in highp vec4 xform_2; +layout(location=5) in highp vec4 xform_3; + + +struct Attractor { + + vec3 pos; + vec3 dir; + float radius; + float eat_radius; + float strength; + float attenuation; +}; + +#define MAX_ATTRACTORS 64 + +uniform bool emitting; +uniform float system_phase; +uniform float prev_system_phase; +uniform int total_particles; +uniform float explosiveness; +uniform float randomness; +uniform float time; +uniform float delta; + +uniform int attractor_count; +uniform Attractor attractors[MAX_ATTRACTORS]; +uniform bool clear; +uniform uint cycle; +uniform float lifetime; +uniform mat4 emission_transform; +uniform uint random_seed; + + +out highp vec4 out_color; //tfb: +out highp vec4 out_velocity_active; //tfb: +out highp vec4 out_custom; //tfb: +out highp vec4 out_xform_1; //tfb: +out highp vec4 out_xform_2; //tfb: +out highp vec4 out_xform_3; //tfb: + + +#if defined(USE_MATERIAL) + +layout(std140) uniform UniformData { //ubo:0 + +MATERIAL_UNIFORMS + +}; + +#endif + + +VERTEX_SHADER_GLOBALS + +uint hash(uint x) { + + x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b); + x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b); + x = (x >> uint(16)) ^ x; + return x; +} + + +void main() { + +#ifdef PARTICLES_COPY + + out_color=color; + out_velocity_active=velocity_active; + out_custom = custom; + out_xform_1 = xform_1; + out_xform_2 = xform_2; + out_xform_3 = xform_3; + +#else + + bool apply_forces=true; + bool apply_velocity=true; + float local_delta=delta; + + float mass = 1.0; + + float restart_phase = float(gl_VertexID)/float(total_particles); + + if (randomness>0.0) { + uint seed = cycle; + if (restart_phase >= system_phase) { + seed-=uint(1); + } + seed*=uint(total_particles); + seed+=uint(gl_VertexID); + float random = float(hash(seed) % uint(65536)) / 65536.0; + restart_phase+=randomness * random * 1.0 / float(total_particles); + } + + restart_phase*= (1.0-explosiveness); + bool restart=false; + bool shader_active = velocity_active.a > 0.5; + + if (system_phase > prev_system_phase) { + // restart_phase >= prev_system_phase is used so particles emit in the first frame they are processed + + if (restart_phase >= prev_system_phase && restart_phase < system_phase ) { + restart=true; +#ifdef USE_FRACTIONAL_DELTA + local_delta = (system_phase - restart_phase) * lifetime; +#endif + } + + } else { + if (restart_phase >= prev_system_phase) { + restart=true; +#ifdef USE_FRACTIONAL_DELTA + local_delta = (1.0 - restart_phase + system_phase) * lifetime; +#endif + } else if (restart_phase < system_phase ) { + restart=true; +#ifdef USE_FRACTIONAL_DELTA + local_delta = (system_phase - restart_phase) * lifetime; +#endif + } + } + + uint current_cycle = cycle; + + if (system_phase < restart_phase) { + current_cycle-=uint(1); + } + + uint particle_number = current_cycle * uint(total_particles) + uint(gl_VertexID); + int index = int(gl_VertexID); + + if (restart) { + shader_active=emitting; + } + + mat4 xform; + +#if defined(ENABLE_KEEP_DATA) + if (clear) { +#else + if (clear || restart) { +#endif + out_color=vec4(1.0); + out_velocity_active=vec4(0.0); + out_custom=vec4(0.0); + if (!restart) + shader_active=false; + + xform = mat4( + vec4(1.0,0.0,0.0,0.0), + vec4(0.0,1.0,0.0,0.0), + vec4(0.0,0.0,1.0,0.0), + vec4(0.0,0.0,0.0,1.0) + ); + } else { + out_color=color; + out_velocity_active=velocity_active; + out_custom=custom; + xform = transpose(mat4(xform_1,xform_2,xform_3,vec4(vec3(0.0),1.0))); + } + + if (shader_active) { + //execute shader + + { +VERTEX_SHADER_CODE + } + +#if !defined(DISABLE_FORCE) + + if (false) { + + vec3 force = vec3(0.0); + for(int i=0;i<attractor_count;i++) { + + vec3 rel_vec = xform[3].xyz - attractors[i].pos; + float dist = length(rel_vec); + if (attractors[i].radius < dist) + continue; + if (attractors[i].eat_radius>0.0 && attractors[i].eat_radius > dist) { + out_velocity_active.a=0.0; + } + + rel_vec = normalize(rel_vec); + + float attenuation = pow(dist / attractors[i].radius,attractors[i].attenuation); + + if (attractors[i].dir==vec3(0.0)) { + //towards center + force+=attractors[i].strength * rel_vec * attenuation * mass; + } else { + force+=attractors[i].strength * attractors[i].dir * attenuation *mass; + + } + } + + out_velocity_active.xyz += force * local_delta; + } +#endif + +#if !defined(DISABLE_VELOCITY) + + if (true) { + + xform[3].xyz += out_velocity_active.xyz * local_delta; + } +#endif + } else { + xform=mat4(0.0); + } + + xform = transpose(xform); + + out_velocity_active.a = mix(0.0,1.0,shader_active); + + out_xform_1 = xform[0]; + out_xform_2 = xform[1]; + out_xform_3 = xform[2]; + +#endif //PARTICLES_COPY + +} + +[fragment] + +//any code here is never executed, stuff is filled just so it works + + +#if defined(USE_MATERIAL) + +layout(std140) uniform UniformData { + +MATERIAL_UNIFORMS + +}; + +#endif + +FRAGMENT_SHADER_GLOBALS + +void main() { + + { +LIGHT_SHADER_CODE + } + + { +FRAGMENT_SHADER_CODE + } +} diff --git a/drivers/gles2/shaders/resolve.glsl b/drivers/gles2/shaders/resolve.glsl new file mode 100644 index 0000000000..0b50a9c57b --- /dev/null +++ b/drivers/gles2/shaders/resolve.glsl @@ -0,0 +1,44 @@ +[vertex] + + +layout(location=0) in highp vec4 vertex_attrib; +layout(location=4) in vec2 uv_in; + +out vec2 uv_interp; + + +void main() { + + uv_interp = uv_in; + gl_Position = vertex_attrib; +} + +[fragment] + +#if !defined(GLES_OVER_GL) +precision mediump float; +#endif + +in vec2 uv_interp; +uniform sampler2D source_specular; //texunit:0 +uniform sampler2D source_ssr; //texunit:1 + +uniform vec2 pixel_size; + +in vec2 uv2_interp; + +layout(location = 0) out vec4 frag_color; + +void main() { + + vec4 specular = texture( source_specular, uv_interp ); + +#ifdef USE_SSR + + vec4 ssr = textureLod(source_ssr,uv_interp,0.0); + specular.rgb = mix(specular.rgb,ssr.rgb*specular.a,ssr.a); +#endif + + frag_color = vec4(specular.rgb,1.0); +} + diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl new file mode 100644 index 0000000000..79b989be4a --- /dev/null +++ b/drivers/gles2/shaders/scene.glsl @@ -0,0 +1,2113 @@ +[vertex] + +#define M_PI 3.14159265359 + +/* +from VisualServer: + +ARRAY_VERTEX=0, +ARRAY_NORMAL=1, +ARRAY_TANGENT=2, +ARRAY_COLOR=3, +ARRAY_TEX_UV=4, +ARRAY_TEX_UV2=5, +ARRAY_BONES=6, +ARRAY_WEIGHTS=7, +ARRAY_INDEX=8, +*/ + +//hack to use uv if no uv present so it works with lightmap + + +/* INPUT ATTRIBS */ + +layout(location=0) in highp vec4 vertex_attrib; +layout(location=1) in vec3 normal_attrib; +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) +layout(location=2) in vec4 tangent_attrib; +#endif + +#if defined(ENABLE_COLOR_INTERP) +layout(location=3) in vec4 color_attrib; +#endif + +#if defined(ENABLE_UV_INTERP) +layout(location=4) in vec2 uv_attrib; +#endif + +#if defined(ENABLE_UV2_INTERP) +layout(location=5) in vec2 uv2_attrib; +#endif + +uniform float normal_mult; + +#ifdef USE_SKELETON +layout(location=6) in ivec4 bone_indices; // attrib:6 +layout(location=7) in vec4 bone_weights; // attrib:7 +#endif + +#ifdef USE_INSTANCING + +layout(location=8) in highp vec4 instance_xform0; +layout(location=9) in highp vec4 instance_xform1; +layout(location=10) in highp vec4 instance_xform2; +layout(location=11) in lowp vec4 instance_color; + +#if defined(ENABLE_INSTANCE_CUSTOM) +layout(location=12) in highp vec4 instance_custom_data; +#endif + +#endif + +layout(std140) uniform SceneData { //ubo:0 + + highp mat4 projection_matrix; + highp mat4 inv_projection_matrix; + highp mat4 camera_inverse_matrix; + highp mat4 camera_matrix; + + mediump vec4 ambient_light_color; + mediump vec4 bg_color; + + mediump vec4 fog_color_enabled; + mediump vec4 fog_sun_color_amount; + + mediump float ambient_energy; + mediump float bg_energy; + + mediump float z_offset; + mediump float z_slope_scale; + highp float shadow_dual_paraboloid_render_zfar; + highp float shadow_dual_paraboloid_render_side; + + highp vec2 viewport_size; + highp vec2 screen_pixel_size; + highp vec2 shadow_atlas_pixel_size; + highp vec2 directional_shadow_pixel_size; + + highp float time; + highp float z_far; + mediump float reflection_multiplier; + mediump float subsurface_scatter_width; + mediump float ambient_occlusion_affect_light; + + bool fog_depth_enabled; + highp float fog_depth_begin; + highp float fog_depth_curve; + bool fog_transmit_enabled; + highp float fog_transmit_curve; + bool fog_height_enabled; + highp float fog_height_min; + highp float fog_height_max; + highp float fog_height_curve; + +}; + +uniform highp mat4 world_transform; + + +#ifdef USE_LIGHT_DIRECTIONAL + +layout(std140) uniform DirectionalLightData { //ubo:3 + + highp vec4 light_pos_inv_radius; + mediump vec4 light_direction_attenuation; + mediump vec4 light_color_energy; + mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled, + mediump vec4 light_clamp; + mediump vec4 shadow_color_contact; + highp mat4 shadow_matrix1; + highp mat4 shadow_matrix2; + highp mat4 shadow_matrix3; + highp mat4 shadow_matrix4; + mediump vec4 shadow_split_offsets; +}; + +#endif + +#ifdef USE_VERTEX_LIGHTING +//omni and spot + +struct LightData { + + highp vec4 light_pos_inv_radius; + mediump vec4 light_direction_attenuation; + mediump vec4 light_color_energy; + mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled, + mediump vec4 light_clamp; + mediump vec4 shadow_color_contact; + highp mat4 shadow_matrix; + +}; + + +layout(std140) uniform OmniLightData { //ubo:4 + + LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; +}; + +layout(std140) uniform SpotLightData { //ubo:5 + + LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; +}; + +#ifdef USE_FORWARD_LIGHTING + + +uniform int omni_light_indices[MAX_FORWARD_LIGHTS]; +uniform int omni_light_count; + +uniform int spot_light_indices[MAX_FORWARD_LIGHTS]; +uniform int spot_light_count; + +#endif + +out vec4 diffuse_light_interp; +out vec4 specular_light_interp; + +void light_compute(vec3 N, vec3 L,vec3 V, vec3 light_color, float roughness, inout vec3 diffuse, inout vec3 specular) { + + float dotNL = max(dot(N,L), 0.0 ); + diffuse += dotNL * light_color / M_PI; + + if (roughness > 0.0) { + + vec3 H = normalize(V + L); + float dotNH = max(dot(N,H), 0.0 ); + float intensity = pow( dotNH, (1.0-roughness) * 256.0); + specular += light_color * intensity; + + } +} + +void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal, float roughness,inout vec3 diffuse, inout vec3 specular) { + + vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex; + float light_length = length( light_rel_vec ); + float normalized_distance = light_length*omni_lights[idx].light_pos_inv_radius.w; + vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.0), omni_lights[idx].light_direction_attenuation.w )); + + light_compute(normal,normalize(light_rel_vec),eye_vec,omni_lights[idx].light_color_energy.rgb * light_attenuation,roughness,diffuse,specular); + +} + +void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, float roughness, inout vec3 diffuse, inout vec3 specular) { + + vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex; + float light_length = length( light_rel_vec ); + float normalized_distance = light_length*spot_lights[idx].light_pos_inv_radius.w; + vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.001), spot_lights[idx].light_direction_attenuation.w )); + vec3 spot_dir = spot_lights[idx].light_direction_attenuation.xyz; + float spot_cutoff=spot_lights[idx].light_params.y; + float scos = max(dot(-normalize(light_rel_vec), spot_dir),spot_cutoff); + float spot_rim = (1.0 - scos) / (1.0 - spot_cutoff); + light_attenuation *= 1.0 - pow( max(spot_rim,0.001), spot_lights[idx].light_params.x); + + + light_compute(normal,normalize(light_rel_vec),eye_vec,spot_lights[idx].light_color_energy.rgb*light_attenuation,roughness,diffuse,specular); +} + + +#endif + +/* Varyings */ + +out highp vec3 vertex_interp; +out vec3 normal_interp; + +#if defined(ENABLE_COLOR_INTERP) +out vec4 color_interp; +#endif + +#if defined(ENABLE_UV_INTERP) +out vec2 uv_interp; +#endif + +#if defined(ENABLE_UV2_INTERP) +out vec2 uv2_interp; +#endif + + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) +out vec3 tangent_interp; +out vec3 binormal_interp; +#endif + + + + + +#if defined(USE_MATERIAL) + +layout(std140) uniform UniformData { //ubo:1 + +MATERIAL_UNIFORMS + +}; + +#endif + +VERTEX_SHADER_GLOBALS + +#ifdef RENDER_DEPTH_DUAL_PARABOLOID + +out highp float dp_clip; + +#endif + +#define SKELETON_TEXTURE_WIDTH 256 + +#ifdef USE_SKELETON +uniform highp sampler2D skeleton_texture; //texunit:-1 +#endif + +out highp vec4 position_interp; + +// FIXME: This triggers a Mesa bug that breaks rendering, so disabled for now. +// See GH-13450 and https://bugs.freedesktop.org/show_bug.cgi?id=100316 +//invariant gl_Position; + +void main() { + + highp vec4 vertex = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0); + + mat4 world_matrix = world_transform; + + +#ifdef USE_INSTANCING + + { + highp mat4 m=mat4(instance_xform0,instance_xform1,instance_xform2,vec4(0.0,0.0,0.0,1.0)); + world_matrix = world_matrix * transpose(m); + } +#endif + + vec3 normal = normal_attrib * normal_mult; + + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) + vec3 tangent = tangent_attrib.xyz; + tangent*=normal_mult; + float binormalf = tangent_attrib.a; +#endif + +#if defined(ENABLE_COLOR_INTERP) + color_interp = color_attrib; +#if defined(USE_INSTANCING) + color_interp *= instance_color; +#endif + +#endif + +#ifdef USE_SKELETON + { + //skeleton transform + ivec2 tex_ofs = ivec2( bone_indices.x%256, (bone_indices.x/256)*3 ); + highp mat3x4 m = mat3x4( + texelFetch(skeleton_texture,tex_ofs,0), + texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0), + texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0) + ) * bone_weights.x; + + tex_ofs = ivec2( bone_indices.y%256, (bone_indices.y/256)*3 ); + + m+= mat3x4( + texelFetch(skeleton_texture,tex_ofs,0), + texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0), + texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0) + ) * bone_weights.y; + + tex_ofs = ivec2( bone_indices.z%256, (bone_indices.z/256)*3 ); + + m+= mat3x4( + texelFetch(skeleton_texture,tex_ofs,0), + texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0), + texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0) + ) * bone_weights.z; + + + tex_ofs = ivec2( bone_indices.w%256, (bone_indices.w/256)*3 ); + + m+= mat3x4( + texelFetch(skeleton_texture,tex_ofs,0), + texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0), + texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0) + ) * bone_weights.w; + + + vertex.xyz = vertex * m; + + normal = vec4(normal,0.0) * m; +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) + tangent.xyz = vec4(tangent.xyz,0.0) * m; +#endif + } +#endif + + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) + + vec3 binormal = normalize( cross(normal,tangent) * binormalf ); +#endif + +#if defined(ENABLE_UV_INTERP) + uv_interp = uv_attrib; +#endif + +#if defined(ENABLE_UV2_INTERP) + uv2_interp = uv2_attrib; +#endif + +#if defined(USE_INSTANCING) && defined(ENABLE_INSTANCE_CUSTOM) + vec4 instance_custom = instance_custom_data; +#else + vec4 instance_custom = vec4(0.0); +#endif + + highp mat4 modelview = camera_inverse_matrix * world_matrix; + highp mat4 local_projection = projection_matrix; + +//using world coordinates +#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED) + + vertex = world_matrix * vertex; + normal = normalize((world_matrix * vec4(normal,0.0)).xyz); + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) + + tangent = normalize((world_matrix * vec4(tangent,0.0)).xyz); + binormal = normalize((world_matrix * vec4(binormal,0.0)).xyz); +#endif +#endif + + float roughness=0.0; + +//defines that make writing custom shaders easier +#define projection_matrix local_projection +#define world_transform world_matrix +{ + +VERTEX_SHADER_CODE + +} + + + +//using local coordinates (default) +#if !defined(SKIP_TRANSFORM_USED) && !defined(VERTEX_WORLD_COORDS_USED) + + vertex = modelview * vertex; + normal = normalize((modelview * vec4(normal,0.0)).xyz); + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) + + tangent = normalize((modelview * vec4(tangent,0.0)).xyz); + binormal = normalize((modelview * vec4(binormal,0.0)).xyz); +#endif +#endif + +//using world coordinates +#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED) + + vertex = camera_inverse_matrix * vertex; + normal = normalize((camera_inverse_matrix * vec4(normal,0.0)).xyz); + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) + + tangent = normalize((camera_inverse_matrix * vec4(tangent,0.0)).xyz); + binormal = normalize((camera_inverse_matrix * vec4(binormal,0.0)).xyz); +#endif +#endif + + vertex_interp = vertex.xyz; + normal_interp = normal; + + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) + tangent_interp = tangent; + binormal_interp = binormal; +#endif + + +#ifdef RENDER_DEPTH + + +#ifdef RENDER_DEPTH_DUAL_PARABOLOID + + vertex_interp.z*= shadow_dual_paraboloid_render_side; + normal_interp.z*= shadow_dual_paraboloid_render_side; + + dp_clip=vertex_interp.z; //this attempts to avoid noise caused by objects sent to the other parabolloid side due to bias + + //for dual paraboloid shadow mapping, this is the fastest but least correct way, as it curves straight edges + + highp vec3 vtx = vertex_interp+normalize(vertex_interp)*z_offset; + highp float distance = length(vtx); + vtx = normalize(vtx); + vtx.xy/=1.0-vtx.z; + vtx.z=(distance/shadow_dual_paraboloid_render_zfar); + vtx.z=vtx.z * 2.0 - 1.0; + + vertex.xyz=vtx; + vertex.w=1.0; + + +#else + + float z_ofs = z_offset; + z_ofs += (1.0-abs(normal_interp.z))*z_slope_scale; + vertex_interp.z-=z_ofs; + +#endif //RENDER_DEPTH_DUAL_PARABOLOID + +#endif //RENDER_DEPTH + + gl_Position = projection_matrix * vec4(vertex_interp,1.0); + + position_interp=gl_Position; + +#ifdef USE_VERTEX_LIGHTING + + diffuse_light_interp=vec4(0.0); + specular_light_interp=vec4(0.0); + +#ifdef USE_FORWARD_LIGHTING + + for(int i=0;i<omni_light_count;i++) { + light_process_omni(omni_light_indices[i],vertex_interp,-normalize( vertex_interp ),normal_interp,roughness,diffuse_light_interp.rgb,specular_light_interp.rgb); + } + + for(int i=0;i<spot_light_count;i++) { + light_process_spot(spot_light_indices[i],vertex_interp,-normalize( vertex_interp ),normal_interp,roughness,diffuse_light_interp.rgb,specular_light_interp.rgb); + } +#endif + +#ifdef USE_LIGHT_DIRECTIONAL + + vec3 directional_diffuse = vec3(0.0); + vec3 directional_specular = vec3(0.0); + light_compute(normal_interp,-light_direction_attenuation.xyz,-normalize( vertex_interp ),light_color_energy.rgb,roughness,directional_diffuse,directional_specular); + + float diff_avg = dot(diffuse_light_interp.rgb,vec3(0.33333)); + float diff_dir_avg = dot(directional_diffuse,vec3(0.33333)); + if (diff_avg>0.0) { + diffuse_light_interp.a=diff_dir_avg/(diff_avg+diff_dir_avg); + } else { + diffuse_light_interp.a=1.0; + } + + diffuse_light_interp.rgb+=directional_diffuse; + + float spec_avg = dot(specular_light_interp.rgb,vec3(0.33333)); + float spec_dir_avg = dot(directional_specular,vec3(0.33333)); + if (spec_avg>0.0) { + specular_light_interp.a=spec_dir_avg/(spec_avg+spec_dir_avg); + } else { + specular_light_interp.a=1.0; + } + + specular_light_interp.rgb+=directional_specular; + +#endif //USE_LIGHT_DIRECTIONAL + + +#endif // USE_VERTEX_LIGHTING + +} + + +[fragment] + +/* texture unit usage, N is max_texture_unity-N + +1-skeleton +2-radiance +3-reflection_atlas +4-directional_shadow +5-shadow_atlas +6-decal_atlas +7-screen +8-depth +9-probe1 +10-probe2 + +*/ + +uniform highp mat4 world_transform; + +#define M_PI 3.14159265359 + +/* Varyings */ + +#if defined(ENABLE_COLOR_INTERP) +in vec4 color_interp; +#endif + +#if defined(ENABLE_UV_INTERP) +in vec2 uv_interp; +#endif + +#if defined(ENABLE_UV2_INTERP) +in vec2 uv2_interp; +#endif + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) +in vec3 tangent_interp; +in vec3 binormal_interp; +#endif + +in highp vec3 vertex_interp; +in vec3 normal_interp; + + +/* PBR CHANNELS */ + +//used on forward mainly +uniform bool no_ambient_light; + + + +#ifdef USE_RADIANCE_MAP + + + +layout(std140) uniform Radiance { //ubo:2 + + mat4 radiance_inverse_xform; + float radiance_ambient_contribution; + +}; + +#define RADIANCE_MAX_LOD 5.0 + +#ifdef USE_RADIANCE_MAP_ARRAY + +uniform sampler2DArray radiance_map; //texunit:-2 + +vec3 textureDualParaboloid(sampler2DArray p_tex, vec3 p_vec,float p_roughness) { + + vec3 norm = normalize(p_vec); + norm.xy/=1.0+abs(norm.z); + norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); + + // we need to lie the derivatives (normg) and assume that DP side is always the same + // to get proper texture filtering + vec2 normg=norm.xy; + if (norm.z>0.0) { + norm.y=0.5-norm.y+0.5; + } + + // thanks to OpenGL spec using floor(layer + 0.5) for texture arrays, + // it's easy to have precision errors using fract() to interpolate layers + // as such, using fixed point to ensure it works. + + float index = p_roughness * RADIANCE_MAX_LOD; + int indexi = int(index * 256.0); + vec3 base = textureGrad(p_tex, vec3(norm.xy, float(indexi/256)),dFdx(normg),dFdy(normg)).xyz; + vec3 next = textureGrad(p_tex, vec3(norm.xy, float(indexi/256+1)),dFdx(normg),dFdy(normg)).xyz; + return mix(base,next,float(indexi%256)/256.0); +} + +#else + +uniform sampler2D radiance_map; //texunit:-2 + +vec3 textureDualParaboloid(sampler2D p_tex, vec3 p_vec,float p_roughness) { + + vec3 norm = normalize(p_vec); + norm.xy/=1.0+abs(norm.z); + norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); + if (norm.z>0.0) { + norm.y=0.5-norm.y+0.5; + } + return textureLod(p_tex, norm.xy, p_roughness * RADIANCE_MAX_LOD).xyz; +} + +#endif + +#endif + +/* Material Uniforms */ + + + +#if defined(USE_MATERIAL) + +layout(std140) uniform UniformData { + +MATERIAL_UNIFORMS + +}; + +#endif + +FRAGMENT_SHADER_GLOBALS + +layout(std140) uniform SceneData { + + highp mat4 projection_matrix; + highp mat4 inv_projection_matrix; + highp mat4 camera_inverse_matrix; + highp mat4 camera_matrix; + + mediump vec4 ambient_light_color; + mediump vec4 bg_color; + + mediump vec4 fog_color_enabled; + mediump vec4 fog_sun_color_amount; + + mediump float ambient_energy; + mediump float bg_energy; + + mediump float z_offset; + mediump float z_slope_scale; + highp float shadow_dual_paraboloid_render_zfar; + highp float shadow_dual_paraboloid_render_side; + + highp vec2 viewport_size; + highp vec2 screen_pixel_size; + highp vec2 shadow_atlas_pixel_size; + highp vec2 directional_shadow_pixel_size; + + highp float time; + highp float z_far; + mediump float reflection_multiplier; + mediump float subsurface_scatter_width; + mediump float ambient_occlusion_affect_light; + + bool fog_depth_enabled; + highp float fog_depth_begin; + highp float fog_depth_curve; + bool fog_transmit_enabled; + highp float fog_transmit_curve; + bool fog_height_enabled; + highp float fog_height_min; + highp float fog_height_max; + highp float fog_height_curve; +}; + +//directional light data + +#ifdef USE_LIGHT_DIRECTIONAL + +layout(std140) uniform DirectionalLightData { + + highp vec4 light_pos_inv_radius; + mediump vec4 light_direction_attenuation; + mediump vec4 light_color_energy; + mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled, + mediump vec4 light_clamp; + mediump vec4 shadow_color_contact; + highp mat4 shadow_matrix1; + highp mat4 shadow_matrix2; + highp mat4 shadow_matrix3; + highp mat4 shadow_matrix4; + mediump vec4 shadow_split_offsets; +}; + + +uniform highp sampler2DShadow directional_shadow; //texunit:-4 + +#endif + +#ifdef USE_VERTEX_LIGHTING +in vec4 diffuse_light_interp; +in vec4 specular_light_interp; +#endif +//omni and spot + +struct LightData { + + highp vec4 light_pos_inv_radius; + mediump vec4 light_direction_attenuation; + mediump vec4 light_color_energy; + mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled, + mediump vec4 light_clamp; + mediump vec4 shadow_color_contact; + highp mat4 shadow_matrix; + +}; + + +layout(std140) uniform OmniLightData { //ubo:4 + + LightData omni_lights[MAX_LIGHT_DATA_STRUCTS]; +}; + +layout(std140) uniform SpotLightData { //ubo:5 + + LightData spot_lights[MAX_LIGHT_DATA_STRUCTS]; +}; + + +uniform highp sampler2DShadow shadow_atlas; //texunit:-5 + + +struct ReflectionData { + + mediump vec4 box_extents; + mediump vec4 box_offset; + mediump vec4 params; // intensity, 0, interior , boxproject + mediump vec4 ambient; //ambient color, energy + mediump vec4 atlas_clamp; + highp mat4 local_matrix; //up to here for spot and omni, rest is for directional + //notes: for ambientblend, use distance to edge to blend between already existing global environment +}; + +layout(std140) uniform ReflectionProbeData { //ubo:6 + + ReflectionData reflections[MAX_REFLECTION_DATA_STRUCTS]; +}; +uniform mediump sampler2D reflection_atlas; //texunit:-3 + + +#ifdef USE_FORWARD_LIGHTING + +uniform int omni_light_indices[MAX_FORWARD_LIGHTS]; +uniform int omni_light_count; + +uniform int spot_light_indices[MAX_FORWARD_LIGHTS]; +uniform int spot_light_count; + +uniform int reflection_indices[MAX_FORWARD_LIGHTS]; +uniform int reflection_count; + +#endif + + +#if defined(SCREEN_TEXTURE_USED) + +uniform highp sampler2D screen_texture; //texunit:-7 + +#endif + +#ifdef USE_MULTIPLE_RENDER_TARGETS + +layout(location=0) out vec4 diffuse_buffer; +layout(location=1) out vec4 specular_buffer; +layout(location=2) out vec4 normal_mr_buffer; +#if defined(ENABLE_SSS) +layout(location=3) out float sss_buffer; +#endif + +#else + +layout(location=0) out vec4 frag_color; + +#endif + +in highp vec4 position_interp; +uniform highp sampler2D depth_buffer; //texunit:-8 + +#ifdef USE_CONTACT_SHADOWS + +float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) { + + if (abs(dir.z)>0.99) + return 1.0; + + vec3 endpoint = pos+dir*max_distance; + vec4 source = position_interp; + vec4 dest = projection_matrix * vec4(endpoint, 1.0); + + vec2 from_screen = (source.xy / source.w) * 0.5 + 0.5; + vec2 to_screen = (dest.xy / dest.w) * 0.5 + 0.5; + + vec2 screen_rel = to_screen - from_screen; + + if (length(screen_rel)<0.00001) + return 1.0; //too small, don't do anything + + /*float pixel_size; //approximate pixel size + + if (screen_rel.x > screen_rel.y) { + + pixel_size = abs((pos.x-endpoint.x)/(screen_rel.x/screen_pixel_size.x)); + } else { + pixel_size = abs((pos.y-endpoint.y)/(screen_rel.y/screen_pixel_size.y)); + + }*/ + vec4 bias = projection_matrix * vec4(pos+vec3(0.0,0.0,0.04), 1.0); //todo un-harcode the 0.04 + + + + vec2 pixel_incr = normalize(screen_rel)*screen_pixel_size; + + + float steps = length(screen_rel) / length(pixel_incr); + steps = min(2000.0,steps); //put a limit to avoid freezing in some strange situation + //steps=10.0; + + vec4 incr = (dest - source)/steps; + float ratio=0.0; + float ratio_incr = 1.0/steps; + + while(steps>0.0) { + source += incr*2.0; + bias+=incr*2.0; + + vec3 uv_depth = (source.xyz / source.w) * 0.5 + 0.5; + float depth = texture(depth_buffer,uv_depth.xy).r; + + if (depth < uv_depth.z) { + if (depth > (bias.z/bias.w) * 0.5 + 0.5) { + return min(pow(ratio,4.0),1.0); + } else { + return 1.0; + } + } + + + ratio+=ratio_incr; + steps-=1.0; + } + + return 1.0; +} + +#endif + + +// This returns the G_GGX function divided by 2 cos_theta_m, where in practice cos_theta_m is either N.L or N.V. +// We're dividing this factor off because the overall term we'll end up looks like +// (see, for example, the first unnumbered equation in B. Burley, "Physically Based Shading at Disney", SIGGRAPH 2012): +// +// F(L.V) D(N.H) G(N.L) G(N.V) / (4 N.L N.V) +// +// We're basically regouping this as +// +// F(L.V) D(N.H) [G(N.L)/(2 N.L)] [G(N.V) / (2 N.V)] +// +// and thus, this function implements the [G(N.m)/(2 N.m)] part with m = L or V. +// +// The contents of the D and G (G1) functions (GGX) are taken from +// E. Heitz, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs", J. Comp. Graph. Tech. 3 (2) (2014). +// Eqns 71-72 and 85-86 (see also Eqns 43 and 80). + +float G_GGX_2cos(float cos_theta_m, float alpha) { + // Schlick's approximation + // C. Schlick, "An Inexpensive BRDF Model for Physically-based Rendering", Computer Graphics Forum. 13 (3): 233 (1994) + // Eq. (19), although see Heitz (2014) the about the problems with his derivation. + // It nevertheless approximates GGX well with k = alpha/2. + float k = 0.5*alpha; + return 0.5 / (cos_theta_m * (1.0 - k) + k); + + // float cos2 = cos_theta_m*cos_theta_m; + // float sin2 = (1.0-cos2); + // return 1.0 /( cos_theta_m + sqrt(cos2 + alpha*alpha*sin2) ); +} + +float D_GGX(float cos_theta_m, float alpha) { + float alpha2 = alpha*alpha; + float d = 1.0 + (alpha2-1.0)*cos_theta_m*cos_theta_m; + return alpha2/(M_PI * d * d); +} + +float G_GGX_anisotropic_2cos(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { + float cos2 = cos_theta_m * cos_theta_m; + float sin2 = (1.0-cos2); + float s_x = alpha_x * cos_phi; + float s_y = alpha_y * sin_phi; + return 1.0 / (cos_theta_m + sqrt(cos2 + (s_x*s_x + s_y*s_y)*sin2 )); +} + +float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { + float cos2 = cos_theta_m * cos_theta_m; + float sin2 = (1.0-cos2); + float r_x = cos_phi/alpha_x; + float r_y = sin_phi/alpha_y; + float d = cos2 + sin2*(r_x * r_x + r_y * r_y); + return 1.0 / (M_PI * alpha_x * alpha_y * d * d ); +} + + +float SchlickFresnel(float u) +{ + float m = 1.0-u; + float m2 = m*m; + return m2*m2*m; // pow(m,5) +} + +float GTR1(float NdotH, float a) +{ + if (a >= 1.0) return 1.0/M_PI; + float a2 = a*a; + float t = 1.0 + (a2-1.0)*NdotH*NdotH; + return (a2-1.0) / (M_PI*log(a2)*t); +} + +vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) { + float dielectric = (0.034 * 2.0) * specular; + // energy conservation + return mix(vec3(dielectric), albedo, metallic); // TODO: reference? +} + +void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) { + +#if defined(USE_LIGHT_SHADER_CODE) +//light is written by the light shader + + vec3 normal = N; + vec3 albedo = diffuse_color; + vec3 light = L; + vec3 view = V; + +LIGHT_SHADER_CODE + + +#else + float NdotL = dot(N,L); + float cNdotL = max(NdotL, 0.0); // clamped NdotL + float NdotV = dot(N, V); + float cNdotV = max(NdotV, 0.0); + + if (metallic < 1.0) { +#if defined(DIFFUSE_OREN_NAYAR) + vec3 diffuse_brdf_NL; +#else + float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance +#endif + + +#if defined(DIFFUSE_LAMBERT_WRAP) + //energy conserving lambert wrap shader + diffuse_brdf_NL = max(0.0,(NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness))); + +#elif defined(DIFFUSE_OREN_NAYAR) + + { + // see http://mimosa-pudica.net/improved-oren-nayar.html + float LdotV = dot(L, V); + + + float s = LdotV - NdotL * NdotV; + float t = mix(1.0, max(NdotL, NdotV), step(0.0, s)); + + float sigma2 = roughness * roughness; // TODO: this needs checking + vec3 A = 1.0 + sigma2 * (- 0.5 / (sigma2 + 0.33) + 0.17*diffuse_color / (sigma2 + 0.13) ); + float B = 0.45 * sigma2 / (sigma2 + 0.09); + + diffuse_brdf_NL = cNdotL * (A + vec3(B) * s / t) * (1.0 / M_PI); + } + +#elif defined(DIFFUSE_TOON) + + diffuse_brdf_NL = smoothstep(-roughness,max(roughness,0.01),NdotL); + +#elif defined(DIFFUSE_BURLEY) + + { + + + vec3 H = normalize(V + L); + float cLdotH = max(0.0,dot(L, H)); + + float FD90 = 0.5 + 2.0 * cLdotH * cLdotH * roughness; + float FdV = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotV); + float FdL = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotL); + diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL; + /* + float energyBias = mix(roughness, 0.0, 0.5); + float energyFactor = mix(roughness, 1.0, 1.0 / 1.51); + float fd90 = energyBias + 2.0 * VoH * VoH * roughness; + float f0 = 1.0; + float lightScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotL, 5.0); + float viewScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotV, 5.0); + + diffuse_brdf_NL = lightScatter * viewScatter * energyFactor;*/ + } +#else + //lambert + diffuse_brdf_NL = cNdotL * (1.0 / M_PI); +#endif + +#if defined(TRANSMISSION_USED) + diffuse_light += light_color * diffuse_color * mix(vec3(diffuse_brdf_NL), vec3(M_PI), transmission) * attenuation; +#else + diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation; +#endif + + + +#if defined(LIGHT_USE_RIM) + float rim_light = pow(1.0-cNdotV, (1.0-roughness)*16.0); + diffuse_light += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color; +#endif + } + + + if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely + + + // D + +#if defined(SPECULAR_BLINN) + + vec3 H = normalize(V + L); + float cNdotH = max(dot(N,H), 0.0 ); + float intensity = pow( cNdotH, (1.0-roughness) * 256.0); + specular_light += light_color * intensity * specular_blob_intensity * attenuation; + +#elif defined(SPECULAR_PHONG) + + vec3 R = normalize(-reflect(L,N)); + float cRdotV = max(0.0,dot(R,V)); + float intensity = pow( cRdotV, (1.0-roughness) * 256.0); + specular_light += light_color * intensity * specular_blob_intensity * attenuation; + +#elif defined(SPECULAR_TOON) + + vec3 R = normalize(-reflect(L,N)); + float RdotV = dot(R,V); + float mid = 1.0-roughness; + mid*=mid; + float intensity = smoothstep(mid-roughness*0.5, mid+roughness*0.5, RdotV) * mid; + diffuse_light += light_color * intensity * specular_blob_intensity * attenuation; // write to diffuse_light, as in toon shading you generally want no reflection + +#elif defined(SPECULAR_DISABLED) + //none.. + +#elif defined(SPECULAR_SCHLICK_GGX) + // shlick+ggx as default + + vec3 H = normalize(V + L); + + float cNdotH = max(dot(N,H), 0.0); + float cLdotH = max(dot(L,H), 0.0); + +# if defined(LIGHT_USE_ANISOTROPY) + + float aspect = sqrt(1.0-anisotropy*0.9); + float rx = roughness/aspect; + float ry = roughness*aspect; + float ax = rx*rx; + float ay = ry*ry; + float XdotH = dot( T, H ); + float YdotH = dot( B, H ); + float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); + float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH); + +# else + float alpha = roughness * roughness; + float D = D_GGX(cNdotH, alpha); + float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha); +# endif + // F + float F0 = 1.0; // FIXME + float cLdotH5 = SchlickFresnel(cLdotH); + float F = mix(cLdotH5, 1.0, F0); + + float specular_brdf_NL = cNdotL * D * F * G; + + specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation; +#endif + +#if defined(LIGHT_USE_CLEARCOAT) + if (clearcoat_gloss > 0.0) { +# if !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN) + vec3 H = normalize(V + L); +# endif +# if !defined(SPECULAR_SCHLICK_GGX) + float cNdotH = max(dot(N,H), 0.0); + float cLdotH = max(dot(L,H), 0.0); + float cLdotH5 = SchlickFresnel(cLdotH); +#endif + float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss)); + float Fr = mix(.04, 1.0, cLdotH5); + float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25); + + + float specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL; + + specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation; + } +#endif + } + + +#endif //defined(USE_LIGHT_SHADER_CODE) +} + + +float sample_shadow(highp sampler2DShadow shadow, vec2 shadow_pixel_size, vec2 pos, float depth, vec4 clamp_rect) { + +#ifdef SHADOW_MODE_PCF_13 + + float avg=textureProj(shadow,vec4(pos,depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,0.0),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,0.0),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,shadow_pixel_size.y),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,shadow_pixel_size.y),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,-shadow_pixel_size.y),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,-shadow_pixel_size.y),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x*2.0,0.0),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x*2.0,0.0),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y*2.0),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y*2.0),depth,1.0)); + return avg*(1.0/13.0); + +#elif defined(SHADOW_MODE_PCF_5) + + float avg=textureProj(shadow,vec4(pos,depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,0.0),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,0.0),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y),depth,1.0)); + avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y),depth,1.0)); + return avg*(1.0/5.0); + +#else + + return textureProj(shadow,vec4(pos,depth,1.0)); + +#endif + +} + +#ifdef RENDER_DEPTH_DUAL_PARABOLOID + +in highp float dp_clip; + +#endif + + + +#if 0 +//need to save texture depth for this + +vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 pos, float distance) { + + float scale = 8.25 * (1.0 - translucency) / subsurface_scatter_width; + float d = scale * distance; + + /** + * Armed with the thickness, we can now calculate the color by means of the + * precalculated transmittance profile. + * (It can be precomputed into a texture, for maximum performance): + */ + float dd = -d * d; + vec3 profile = vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) + + vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) + + vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) + + vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) + + vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) + + vec3(0.078, 0.0, 0.0) * exp(dd / 7.41); + + /** + * Using the profile, we finally approximate the transmitted lighting from + * the back of the object: + */ + return profile * clamp(0.3 + dot(light_vec, normal),0.0,1.0); +} +#endif + +void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) { + + vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex; + float light_length = length( light_rel_vec ); + float normalized_distance = light_length*omni_lights[idx].light_pos_inv_radius.w; + vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.0), omni_lights[idx].light_direction_attenuation.w )); + + if (omni_lights[idx].light_params.w>0.5) { + //there is a shadowmap + + highp vec3 splane=(omni_lights[idx].shadow_matrix * vec4(vertex,1.0)).xyz; + float shadow_len=length(splane); + splane=normalize(splane); + vec4 clamp_rect=omni_lights[idx].light_clamp; + + if (splane.z>=0.0) { + + splane.z+=1.0; + + clamp_rect.y+=clamp_rect.w; + + } else { + + splane.z=1.0 - splane.z; + + /* + if (clamp_rect.z<clamp_rect.w) { + clamp_rect.x+=clamp_rect.z; + } else { + clamp_rect.y+=clamp_rect.w; + } + */ + + } + + splane.xy/=splane.z; + splane.xy=splane.xy * 0.5 + 0.5; + splane.z = shadow_len * omni_lights[idx].light_pos_inv_radius.w; + + splane.xy = clamp_rect.xy+splane.xy*clamp_rect.zw; + float shadow = sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,clamp_rect); + +#ifdef USE_CONTACT_SHADOWS + + if (shadow>0.01 && omni_lights[idx].shadow_color_contact.a>0.0) { + + float contact_shadow = contact_shadow_compute(vertex,normalize(light_rel_vec),min(light_length,omni_lights[idx].shadow_color_contact.a)); + shadow=min(shadow,contact_shadow); + + } +#endif + light_attenuation*=mix(omni_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow); + } + + light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb,light_attenuation,albedo,transmission,omni_lights[idx].light_params.z*p_blob_intensity,roughness,metallic,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); + +} + +void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, vec3 transmission,float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) { + + vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex; + float light_length = length( light_rel_vec ); + float normalized_distance = light_length*spot_lights[idx].light_pos_inv_radius.w; + vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.001), spot_lights[idx].light_direction_attenuation.w )); + vec3 spot_dir = spot_lights[idx].light_direction_attenuation.xyz; + float spot_cutoff=spot_lights[idx].light_params.y; + float scos = max(dot(-normalize(light_rel_vec), spot_dir),spot_cutoff); + float spot_rim = (1.0 - scos) / (1.0 - spot_cutoff); + light_attenuation *= 1.0 - pow( max(spot_rim,0.001), spot_lights[idx].light_params.x); + + if (spot_lights[idx].light_params.w>0.5) { + //there is a shadowmap + highp vec4 splane=(spot_lights[idx].shadow_matrix * vec4(vertex,1.0)); + splane.xyz/=splane.w; + + float shadow = sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,spot_lights[idx].light_clamp); + +#ifdef USE_CONTACT_SHADOWS + if (shadow>0.01 && spot_lights[idx].shadow_color_contact.a>0.0) { + + float contact_shadow = contact_shadow_compute(vertex,normalize(light_rel_vec),min(light_length,spot_lights[idx].shadow_color_contact.a)); + shadow=min(shadow,contact_shadow); + + } +#endif + light_attenuation*=mix(spot_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow); + } + + light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb,light_attenuation,albedo,transmission,spot_lights[idx].light_params.z*p_blob_intensity,roughness,metallic,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); + +} + +void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 tangent,float roughness,float anisotropy,vec3 ambient,vec3 skybox, inout highp vec4 reflection_accum,inout highp vec4 ambient_accum) { + + vec3 ref_vec = normalize(reflect(vertex,normal)); + vec3 local_pos = (reflections[idx].local_matrix * vec4(vertex,1.0)).xyz; + vec3 box_extents = reflections[idx].box_extents.xyz; + + if (any(greaterThan(abs(local_pos),box_extents))) { //out of the reflection box + return; + } + + vec3 inner_pos = abs(local_pos / box_extents); + float blend = max(inner_pos.x,max(inner_pos.y,inner_pos.z)); + //make blend more rounded + blend=mix(length(inner_pos),blend,blend); + blend*=blend; + blend=1.001-blend; + + if (reflections[idx].params.x>0.0){// compute reflection + + vec3 local_ref_vec = (reflections[idx].local_matrix * vec4(ref_vec,0.0)).xyz; + + if (reflections[idx].params.w > 0.5) { //box project + + vec3 nrdir = normalize(local_ref_vec); + vec3 rbmax = (box_extents - local_pos)/nrdir; + vec3 rbmin = (-box_extents - local_pos)/nrdir; + + + vec3 rbminmax = mix(rbmin,rbmax,greaterThan(nrdir,vec3(0.0,0.0,0.0))); + + float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z); + vec3 posonbox = local_pos + nrdir * fa; + local_ref_vec = posonbox - reflections[idx].box_offset.xyz; + } + + + vec4 clamp_rect=reflections[idx].atlas_clamp; + vec3 norm = normalize(local_ref_vec); + norm.xy/=1.0+abs(norm.z); + norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); + if (norm.z>0.0) { + norm.y=0.5-norm.y+0.5; + } + + vec2 atlas_uv = norm.xy * clamp_rect.zw + clamp_rect.xy; + atlas_uv = clamp(atlas_uv,clamp_rect.xy,clamp_rect.xy+clamp_rect.zw); + + highp vec4 reflection; + reflection.rgb = textureLod(reflection_atlas,atlas_uv,roughness*5.0).rgb; + + if (reflections[idx].params.z < 0.5) { + reflection.rgb = mix(skybox,reflection.rgb,blend); + } + reflection.rgb*=reflections[idx].params.x; + reflection.a = blend; + reflection.rgb*=reflection.a; + + reflection_accum+=reflection; + } + + if (reflections[idx].ambient.a>0.0) { //compute ambient using skybox + + + vec3 local_amb_vec = (reflections[idx].local_matrix * vec4(normal,0.0)).xyz; + + vec3 splane=normalize(local_amb_vec); + vec4 clamp_rect=reflections[idx].atlas_clamp; + + splane.z*=-1.0; + if (splane.z>=0.0) { + splane.z+=1.0; + clamp_rect.y+=clamp_rect.w; + } else { + splane.z=1.0 - splane.z; + splane.y=-splane.y; + } + + splane.xy/=splane.z; + splane.xy=splane.xy * 0.5 + 0.5; + + splane.xy = splane.xy * clamp_rect.zw + clamp_rect.xy; + splane.xy = clamp(splane.xy,clamp_rect.xy,clamp_rect.xy+clamp_rect.zw); + + highp vec4 ambient_out; + ambient_out.a=blend; + ambient_out.rgb = textureLod(reflection_atlas,splane.xy,5.0).rgb; + ambient_out.rgb=mix(reflections[idx].ambient.rgb,ambient_out.rgb,reflections[idx].ambient.a); + if (reflections[idx].params.z < 0.5) { + ambient_out.rgb = mix(ambient,ambient_out.rgb,blend); + } + + ambient_out.rgb *= ambient_out.a; + ambient_accum+=ambient_out; + } else { + + highp vec4 ambient_out; + ambient_out.a=blend; + ambient_out.rgb=reflections[idx].ambient.rgb; + if (reflections[idx].params.z < 0.5) { + ambient_out.rgb = mix(ambient,ambient_out.rgb,blend); + } + ambient_out.rgb *= ambient_out.a; + ambient_accum+=ambient_out; + + } +} + +#ifdef USE_GI_PROBES + +uniform mediump sampler3D gi_probe1; //texunit:-9 +uniform highp mat4 gi_probe_xform1; +uniform highp vec3 gi_probe_bounds1; +uniform highp vec3 gi_probe_cell_size1; +uniform highp float gi_probe_multiplier1; +uniform highp float gi_probe_bias1; +uniform highp float gi_probe_normal_bias1; +uniform bool gi_probe_blend_ambient1; + +uniform mediump sampler3D gi_probe2; //texunit:-10 +uniform highp mat4 gi_probe_xform2; +uniform highp vec3 gi_probe_bounds2; +uniform highp vec3 gi_probe_cell_size2; +uniform highp float gi_probe_multiplier2; +uniform highp float gi_probe_bias2; +uniform highp float gi_probe_normal_bias2; +uniform bool gi_probe2_enabled; +uniform bool gi_probe_blend_ambient2; + +vec3 voxel_cone_trace(mediump sampler3D probe, vec3 cell_size, vec3 pos, vec3 ambient, bool blend_ambient, vec3 direction, float tan_half_angle, float max_distance, float p_bias) { + + float dist = p_bias;//1.0; //dot(direction,mix(vec3(-1.0),vec3(1.0),greaterThan(direction,vec3(0.0))))*2.0; + float alpha=0.0; + vec3 color = vec3(0.0); + + while(dist < max_distance && alpha < 0.95) { + float diameter = max(1.0, 2.0 * tan_half_angle * dist); + vec4 scolor = textureLod(probe, (pos + dist * direction) * cell_size, log2(diameter) ); + float a = (1.0 - alpha); + color += scolor.rgb * a; + alpha += a * scolor.a; + dist += diameter * 0.5; + } + + if (blend_ambient) { + color.rgb = mix(ambient,color.rgb,min(1.0,alpha/0.95)); + } + + return color; +} + +void gi_probe_compute(mediump sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_size,vec3 pos, vec3 ambient, vec3 environment, bool blend_ambient,float multiplier, mat3 normal_mtx,vec3 ref_vec, float roughness,float p_bias,float p_normal_bias, inout vec4 out_spec, inout vec4 out_diff) { + + + + vec3 probe_pos = (probe_xform * vec4(pos,1.0)).xyz; + vec3 ref_pos = (probe_xform * vec4(pos+ref_vec,1.0)).xyz; + ref_vec = normalize(ref_pos - probe_pos); + + probe_pos+=(probe_xform * vec4(normal_mtx[2],0.0)).xyz*p_normal_bias; + +/* out_diff.rgb = voxel_cone_trace(probe,cell_size,probe_pos,normalize((probe_xform * vec4(ref_vec,0.0)).xyz),0.0 ,100.0); + out_diff.a = 1.0; + return;*/ + //out_diff = vec4(textureLod(probe,probe_pos*cell_size,3.0).rgb,1.0); + //return; + + //this causes corrupted pixels, i have no idea why.. + if (any(bvec2(any(lessThan(probe_pos,vec3(0.0))),any(greaterThan(probe_pos,bounds))))) { + return; + } + + //vec3 blendv = probe_pos/bounds * 2.0 - 1.0; + //float blend = 1.001-max(blendv.x,max(blendv.y,blendv.z)); + float blend=1.0; + + float max_distance = length(bounds); + + //radiance +#ifdef VCT_QUALITY_HIGH + +#define MAX_CONE_DIRS 6 + vec3 cone_dirs[MAX_CONE_DIRS] = vec3[] ( + vec3(0, 0, 1), + vec3(0.866025, 0, 0.5), + vec3(0.267617, 0.823639, 0.5), + vec3(-0.700629, 0.509037, 0.5), + vec3(-0.700629, -0.509037, 0.5), + vec3(0.267617, -0.823639, 0.5) + ); + + float cone_weights[MAX_CONE_DIRS] = float[](0.25, 0.15, 0.15, 0.15, 0.15, 0.15); + float cone_angle_tan = 0.577; + float min_ref_tan = 0.0; +#else + +#define MAX_CONE_DIRS 4 + + vec3 cone_dirs[MAX_CONE_DIRS] = vec3[] ( + vec3(0.707107, 0, 0.707107), + vec3(0, 0.707107, 0.707107), + vec3(-0.707107, 0, 0.707107), + vec3(0, -0.707107, 0.707107) + ); + + float cone_weights[MAX_CONE_DIRS] = float[](0.25, 0.25, 0.25, 0.25); + float cone_angle_tan = 0.98269; + max_distance*=0.5; + float min_ref_tan = 0.2; + +#endif + vec3 light=vec3(0.0); + for(int i=0;i<MAX_CONE_DIRS;i++) { + + vec3 dir = normalize( (probe_xform * vec4(pos + normal_mtx * cone_dirs[i],1.0)).xyz - probe_pos); + light+=cone_weights[i] * voxel_cone_trace(probe,cell_size,probe_pos,ambient,blend_ambient,dir,cone_angle_tan,max_distance,p_bias); + + } + + light*=multiplier; + + out_diff += vec4(light*blend,blend); + + //irradiance + + vec3 irr_light = voxel_cone_trace(probe,cell_size,probe_pos,environment,blend_ambient,ref_vec,max(min_ref_tan,tan(roughness * 0.5 * M_PI)) ,max_distance,p_bias); + + irr_light *= multiplier; + //irr_light=vec3(0.0); + + out_spec += vec4(irr_light*blend,blend); + +} + + +void gi_probes_compute(vec3 pos, vec3 normal, float roughness, inout vec3 out_specular, inout vec3 out_ambient) { + + roughness = roughness * roughness; + + vec3 ref_vec = normalize(reflect(normalize(pos),normal)); + + //find arbitrary tangent and bitangent, then build a matrix + vec3 v0 = abs(normal.z) < 0.999 ? vec3(0, 0, 1) : vec3(0, 1, 0); + vec3 tangent = normalize(cross(v0, normal)); + vec3 bitangent = normalize(cross(tangent, normal)); + mat3 normal_mat = mat3(tangent,bitangent,normal); + + vec4 diff_accum = vec4(0.0); + vec4 spec_accum = vec4(0.0); + + vec3 ambient = out_ambient; + out_ambient = vec3(0.0); + + vec3 environment = out_specular; + + out_specular = vec3(0.0); + + gi_probe_compute(gi_probe1,gi_probe_xform1,gi_probe_bounds1,gi_probe_cell_size1,pos,ambient,environment,gi_probe_blend_ambient1,gi_probe_multiplier1,normal_mat,ref_vec,roughness,gi_probe_bias1,gi_probe_normal_bias1,spec_accum,diff_accum); + + if (gi_probe2_enabled) { + + gi_probe_compute(gi_probe2,gi_probe_xform2,gi_probe_bounds2,gi_probe_cell_size2,pos,ambient,environment,gi_probe_blend_ambient2,gi_probe_multiplier2,normal_mat,ref_vec,roughness,gi_probe_bias2,gi_probe_normal_bias2,spec_accum,diff_accum); + } + + if (diff_accum.a>0.0) { + diff_accum.rgb/=diff_accum.a; + } + + if (spec_accum.a>0.0) { + spec_accum.rgb/=spec_accum.a; + } + + out_specular+=spec_accum.rgb; + out_ambient+=diff_accum.rgb; + +} + +#endif + + + +void main() { + +#ifdef RENDER_DEPTH_DUAL_PARABOLOID + + if (dp_clip>0.0) + discard; +#endif + + //lay out everything, whathever is unused is optimized away anyway + highp vec3 vertex = vertex_interp; + vec3 albedo = vec3(0.8,0.8,0.8); + vec3 transmission = vec3(0.0); + float metallic = 0.0; + float specular = 0.5; + vec3 emission = vec3(0.0,0.0,0.0); + float roughness = 1.0; + float rim = 0.0; + float rim_tint = 0.0; + float clearcoat=0.0; + float clearcoat_gloss=0.0; + float anisotropy = 1.0; + vec2 anisotropy_flow = vec2(1.0,0.0); + +#if defined(ENABLE_AO) + float ao=1.0; + float ao_light_affect=0.0; +#endif + + float alpha = 1.0; + +#ifdef METERIAL_DOUBLESIDED + float side=float(gl_FrontFacing)*2.0-1.0; +#else + float side=1.0; +#endif + + +#if defined(ALPHA_SCISSOR_USED) + float alpha_scissor = 0.5; +#endif + +#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) + vec3 binormal = normalize(binormal_interp)*side; + vec3 tangent = normalize(tangent_interp)*side; +#else + vec3 binormal = vec3(0.0); + vec3 tangent = vec3(0.0); +#endif + vec3 normal = normalize(normal_interp)*side; + +#if defined(ENABLE_UV_INTERP) + vec2 uv = uv_interp; +#endif + +#if defined(ENABLE_UV2_INTERP) + vec2 uv2 = uv2_interp; +#endif + +#if defined(ENABLE_COLOR_INTERP) + vec4 color = color_interp; +#endif + +#if defined(ENABLE_NORMALMAP) + + vec3 normalmap = vec3(0.0); +#endif + + float normaldepth=1.0; + +#if defined(SCREEN_UV_USED) + vec2 screen_uv = gl_FragCoord.xy*screen_pixel_size; +#endif + +#if defined (ENABLE_SSS) + float sss_strength=0.0; +#endif + +{ + + +FRAGMENT_SHADER_CODE + +} + + +#if defined(ALPHA_SCISSOR_USED) + if (alpha<alpha_scissor) { + discard; + } +#endif + +#ifdef USE_OPAQUE_PREPASS + + if (alpha<0.99) { + discard; + } +#endif + +#if defined(ENABLE_NORMALMAP) + + normalmap.xy=normalmap.xy*2.0-1.0; + normalmap.z=sqrt(1.0-dot(normalmap.xy,normalmap.xy)); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc. + + normal = normalize( mix(normal_interp,tangent * normalmap.x + binormal * normalmap.y + normal * normalmap.z,normaldepth) ) * side; + +#endif + +#if defined(LIGHT_USE_ANISOTROPY) + + if (anisotropy>0.01) { + //rotation matrix + mat3 rot = mat3( tangent, binormal, normal ); + //make local to space + tangent = normalize(rot * vec3(anisotropy_flow.x,anisotropy_flow.y,0.0)); + binormal = normalize(rot * vec3(-anisotropy_flow.y,anisotropy_flow.x,0.0)); + } + +#endif + +#ifdef ENABLE_CLIP_ALPHA + if (albedo.a<0.99) { + //used for doublepass and shadowmapping + discard; + } +#endif + +/////////////////////// LIGHTING ////////////////////////////// + + //apply energy conservation + +#ifdef USE_VERTEX_LIGHTING + + vec3 specular_light = specular_light_interp.rgb; + vec3 diffuse_light = diffuse_light_interp.rgb; +#else + + vec3 specular_light = vec3(0.0,0.0,0.0); + vec3 diffuse_light = vec3(0.0,0.0,0.0); + +#endif + + vec3 ambient_light; + vec3 env_reflection_light = vec3(0.0,0.0,0.0); + + vec3 eye_vec = -normalize( vertex_interp ); + + + +#ifdef USE_RADIANCE_MAP + + if (no_ambient_light) { + ambient_light=vec3(0.0,0.0,0.0); + } else { + { + + { //read radiance from dual paraboloid + + vec3 ref_vec = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n); + ref_vec=normalize((radiance_inverse_xform * vec4(ref_vec,0.0)).xyz); + vec3 radiance = textureDualParaboloid(radiance_map,ref_vec,roughness) * bg_energy; + env_reflection_light = radiance; + + } + //no longer a cubemap + //vec3 radiance = textureLod(radiance_cube, r, lod).xyz * ( brdf.x + brdf.y); + + } + + { + + vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz); + vec3 env_ambient=textureDualParaboloid(radiance_map,ambient_dir,1.0) * bg_energy; + + ambient_light=mix(ambient_light_color.rgb,env_ambient,radiance_ambient_contribution); + //ambient_light=vec3(0.0,0.0,0.0); + } + } + +#else + + if (no_ambient_light){ + ambient_light=vec3(0.0,0.0,0.0); + } else { + ambient_light=ambient_light_color.rgb; + } +#endif + + ambient_light*=ambient_energy; + + float specular_blob_intensity=1.0; +#if defined(SPECULAR_TOON) + specular_blob_intensity*=specular * 2.0; +#endif + +#if defined(USE_LIGHT_DIRECTIONAL) + + vec3 light_attenuation=vec3(1.0); + + float depth_z = -vertex.z; +#ifdef LIGHT_DIRECTIONAL_SHADOW + +#ifdef LIGHT_USE_PSSM4 + if (depth_z < shadow_split_offsets.w) { +#elif defined(LIGHT_USE_PSSM2) + if (depth_z < shadow_split_offsets.y) { +#else + if (depth_z < shadow_split_offsets.x) { +#endif //LIGHT_USE_PSSM4 + + vec3 pssm_coord; + float pssm_fade=0.0; + +#ifdef LIGHT_USE_PSSM_BLEND + float pssm_blend; + vec3 pssm_coord2; + bool use_blend=true; +#endif + + +#ifdef LIGHT_USE_PSSM4 + + + if (depth_z < shadow_split_offsets.y) { + + if (depth_z < shadow_split_offsets.x) { + + highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0)); + pssm_coord=splane.xyz/splane.w; + + +#if defined(LIGHT_USE_PSSM_BLEND) + + splane=(shadow_matrix2 * vec4(vertex,1.0)); + pssm_coord2=splane.xyz/splane.w; + pssm_blend=smoothstep(0.0,shadow_split_offsets.x,depth_z); +#endif + + } else { + + highp vec4 splane=(shadow_matrix2 * vec4(vertex,1.0)); + pssm_coord=splane.xyz/splane.w; + +#if defined(LIGHT_USE_PSSM_BLEND) + splane=(shadow_matrix3 * vec4(vertex,1.0)); + pssm_coord2=splane.xyz/splane.w; + pssm_blend=smoothstep(shadow_split_offsets.x,shadow_split_offsets.y,depth_z); +#endif + + } + } else { + + + if (depth_z < shadow_split_offsets.z) { + + highp vec4 splane=(shadow_matrix3 * vec4(vertex,1.0)); + pssm_coord=splane.xyz/splane.w; + +#if defined(LIGHT_USE_PSSM_BLEND) + splane=(shadow_matrix4 * vec4(vertex,1.0)); + pssm_coord2=splane.xyz/splane.w; + pssm_blend=smoothstep(shadow_split_offsets.y,shadow_split_offsets.z,depth_z); +#endif + + } else { + + highp vec4 splane=(shadow_matrix4 * vec4(vertex,1.0)); + pssm_coord=splane.xyz/splane.w; + pssm_fade = smoothstep(shadow_split_offsets.z,shadow_split_offsets.w,depth_z); + +#if defined(LIGHT_USE_PSSM_BLEND) + use_blend=false; + +#endif + + } + } + + + +#endif //LIGHT_USE_PSSM4 + +#ifdef LIGHT_USE_PSSM2 + + if (depth_z < shadow_split_offsets.x) { + + highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0)); + pssm_coord=splane.xyz/splane.w; + + +#if defined(LIGHT_USE_PSSM_BLEND) + + splane=(shadow_matrix2 * vec4(vertex,1.0)); + pssm_coord2=splane.xyz/splane.w; + pssm_blend=smoothstep(0.0,shadow_split_offsets.x,depth_z); +#endif + + } else { + highp vec4 splane=(shadow_matrix2 * vec4(vertex,1.0)); + pssm_coord=splane.xyz/splane.w; + pssm_fade = smoothstep(shadow_split_offsets.x,shadow_split_offsets.y,depth_z); +#if defined(LIGHT_USE_PSSM_BLEND) + use_blend=false; + +#endif + + } + +#endif //LIGHT_USE_PSSM2 + +#if !defined(LIGHT_USE_PSSM4) && !defined(LIGHT_USE_PSSM2) + { //regular orthogonal + highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0)); + pssm_coord=splane.xyz/splane.w; + } +#endif + + + //one one sample + + float shadow = sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord.xy,pssm_coord.z,light_clamp); + +#if defined(LIGHT_USE_PSSM_BLEND) + + if (use_blend) { + shadow=mix(shadow, sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp),pssm_blend); + } +#endif + +#ifdef USE_CONTACT_SHADOWS + if (shadow>0.01 && shadow_color_contact.a>0.0) { + + float contact_shadow = contact_shadow_compute(vertex,-light_direction_attenuation.xyz,shadow_color_contact.a); + shadow=min(shadow,contact_shadow); + + } +#endif + light_attenuation=mix(mix(shadow_color_contact.rgb,vec3(1.0),shadow),vec3(1.0),pssm_fade); + + + } + + +#endif //LIGHT_DIRECTIONAL_SHADOW + +#ifdef USE_VERTEX_LIGHTING + diffuse_light*=mix(vec3(1.0),light_attenuation,diffuse_light_interp.a); + specular_light*=mix(vec3(1.0),light_attenuation,specular_light_interp.a); + +#else + light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb,light_attenuation,albedo,transmission,light_params.z*specular_blob_intensity,roughness,metallic,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); +#endif + + +#endif //#USE_LIGHT_DIRECTIONAL + +#ifdef USE_GI_PROBES + gi_probes_compute(vertex,normal,roughness,env_reflection_light,ambient_light); + +#endif + +#ifdef USE_FORWARD_LIGHTING + + + highp vec4 reflection_accum = vec4(0.0,0.0,0.0,0.0); + highp vec4 ambient_accum = vec4(0.0,0.0,0.0,0.0); + for(int i=0;i<reflection_count;i++) { + reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,env_reflection_light,reflection_accum,ambient_accum); + } + + if (reflection_accum.a>0.0) { + specular_light+=reflection_accum.rgb/reflection_accum.a; + } else { + specular_light+=env_reflection_light; + } + + if (ambient_accum.a>0.0) { + ambient_light+=ambient_accum.rgb/ambient_accum.a; + } + + + +#ifdef USE_VERTEX_LIGHTING + + diffuse_light*=albedo; +#else + + for(int i=0;i<omni_light_count;i++) { + light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,metallic,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light); + } + + for(int i=0;i<spot_light_count;i++) { + light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,metallic,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light); + } + +#endif //USE_VERTEX_LIGHTING + +#endif + + + + +#ifdef RENDER_DEPTH +//nothing happens, so a tree-ssa optimizer will result in no fragment shader :) +#else + + specular_light*=reflection_multiplier; + ambient_light*=albedo; //ambient must be multiplied by albedo at the end + +#if defined(ENABLE_AO) + ambient_light*=ao; + ao_light_affect = mix(1.0,ao,ao_light_affect); + specular_light*=ao_light_affect; + diffuse_light*=ao_light_affect; +#endif + + + + //energy conservation + diffuse_light *= 1.0-metallic; // TODO: avoid all diffuse and ambient light calculations when metallic == 1 up to this point + ambient_light *= 1.0-metallic; + + + { + +#if defined(DIFFUSE_TOON) + //simplify for toon, as + specular_light *= specular * metallic * albedo * 2.0; +#else + // Environment brdf approximation (Lazarov 2013) + // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile + const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); + const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04); + vec4 r = roughness * c0 + c1; + float ndotv = clamp(dot(normal,eye_vec),0.0,1.0); + float a004 = min( r.x * r.x, exp2( -9.28 * ndotv ) ) * r.x + r.y; + vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; + + vec3 specular_color = metallic_to_specular_color(metallic, specular, albedo); + specular_light *= AB.x * specular_color + AB.y; +#endif + + } + + if (fog_color_enabled.a > 0.5) { + + float fog_amount=0.0; + + + +#ifdef USE_LIGHT_DIRECTIONAL + + vec3 fog_color = mix( fog_color_enabled.rgb, fog_sun_color_amount.rgb,fog_sun_color_amount.a * pow(max( dot(normalize(vertex),-light_direction_attenuation.xyz), 0.0),8.0) ); +#else + + vec3 fog_color = fog_color_enabled.rgb; +#endif + + //apply fog + + if (fog_depth_enabled) { + + float fog_z = smoothstep(fog_depth_begin,z_far,length(vertex)); + + fog_amount = pow(fog_z,fog_depth_curve); + if (fog_transmit_enabled) { + vec3 total_light = emission + ambient_light + specular_light + diffuse_light; + float transmit = pow(fog_z,fog_transmit_curve); + fog_color = mix(max(total_light,fog_color),fog_color,transmit); + } + } + + if (fog_height_enabled) { + float y = (camera_matrix * vec4(vertex,1.0)).y; + fog_amount = max(fog_amount,pow(smoothstep(fog_height_min,fog_height_max,y),fog_height_curve)); + } + + float rev_amount = 1.0 - fog_amount; + + + emission = emission * rev_amount + fog_color * fog_amount; + ambient_light*=rev_amount; + specular_light*rev_amount; + diffuse_light*=rev_amount; + + } + +#ifdef USE_MULTIPLE_RENDER_TARGETS + + +#ifdef SHADELESS + diffuse_buffer=vec4(albedo.rgb,0.0); + specular_buffer=vec4(0.0); + +#else + +#if defined(ENABLE_AO) + + float ambient_scale=0.0; // AO is supplied by material +#else + //approximate ambient scale for SSAO, since we will lack full ambient + float max_emission=max(emission.r,max(emission.g,emission.b)); + float max_ambient=max(ambient_light.r,max(ambient_light.g,ambient_light.b)); + float max_diffuse=max(diffuse_light.r,max(diffuse_light.g,diffuse_light.b)); + float total_ambient = max_ambient+max_diffuse+max_emission; + float ambient_scale = (total_ambient>0.0) ? (max_ambient+ambient_occlusion_affect_light*max_diffuse)/total_ambient : 0.0; +#endif //ENABLE_AO + + diffuse_buffer=vec4(emission+diffuse_light+ambient_light,ambient_scale); + specular_buffer=vec4(specular_light,metallic); + +#endif //SHADELESS + + normal_mr_buffer=vec4(normalize(normal)*0.5+0.5,roughness); + +#if defined (ENABLE_SSS) + sss_buffer = sss_strength; +#endif + + +#else //USE_MULTIPLE_RENDER_TARGETS + + +#ifdef SHADELESS + frag_color=vec4(albedo,alpha); +#else + frag_color=vec4(emission+ambient_light+diffuse_light+specular_light,alpha); +#endif //SHADELESS + + +#endif //USE_MULTIPLE_RENDER_TARGETS + + + +#endif //RENDER_DEPTH + + +} diff --git a/drivers/gles2/shaders/screen_space_reflection.glsl b/drivers/gles2/shaders/screen_space_reflection.glsl new file mode 100644 index 0000000000..b2e6f7a736 --- /dev/null +++ b/drivers/gles2/shaders/screen_space_reflection.glsl @@ -0,0 +1,318 @@ +[vertex] + + +layout(location=0) in highp vec4 vertex_attrib; +layout(location=4) in vec2 uv_in; + +out vec2 uv_interp; +out vec2 pos_interp; + +void main() { + + uv_interp = uv_in; + gl_Position = vertex_attrib; + pos_interp.xy=gl_Position.xy; +} + +[fragment] + + +in vec2 uv_interp; +in vec2 pos_interp; + +uniform sampler2D source_diffuse; //texunit:0 +uniform sampler2D source_normal_roughness; //texunit:1 +uniform sampler2D source_depth; //texunit:2 + +uniform float camera_z_near; +uniform float camera_z_far; + +uniform vec2 viewport_size; +uniform vec2 pixel_size; + +uniform float filter_mipmap_levels; + +uniform mat4 inverse_projection; +uniform mat4 projection; + +uniform int num_steps; +uniform float depth_tolerance; +uniform float distance_fade; +uniform float curve_fade_in; + + +layout(location = 0) out vec4 frag_color; + + +vec2 view_to_screen(vec3 view_pos,out float w) { + vec4 projected = projection * vec4(view_pos, 1.0); + projected.xyz /= projected.w; + projected.xy = projected.xy * 0.5 + 0.5; + w=projected.w; + return projected.xy; +} + + + +#define M_PI 3.14159265359 + +void main() { + + + //// + + vec4 diffuse = texture( source_diffuse, uv_interp ); + vec4 normal_roughness = texture( source_normal_roughness, uv_interp); + + vec3 normal; + + normal = normal_roughness.xyz*2.0-1.0; + + float roughness = normal_roughness.w; + + float depth_tex = texture(source_depth,uv_interp).r; + + vec4 world_pos = inverse_projection * vec4( uv_interp*2.0-1.0, depth_tex*2.0-1.0, 1.0 ); + vec3 vertex = world_pos.xyz/world_pos.w; + + vec3 view_dir = normalize(vertex); + vec3 ray_dir = normalize(reflect(view_dir, normal)); + + if (dot(ray_dir,normal)<0.001) { + frag_color=vec4(0.0); + return; + } + //ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0); + + //ray_dir = normalize(vec3(1,1,-1)); + + + //////////////// + + + //make ray length and clip it against the near plane (don't want to trace beyond visible) + float ray_len = (vertex.z + ray_dir.z * camera_z_far) > -camera_z_near ? (-camera_z_near - vertex.z) / ray_dir.z : camera_z_far; + vec3 ray_end = vertex + ray_dir*ray_len; + + float w_begin; + vec2 vp_line_begin = view_to_screen(vertex,w_begin); + float w_end; + vec2 vp_line_end = view_to_screen( ray_end, w_end); + vec2 vp_line_dir = vp_line_end-vp_line_begin; + + //we need to interpolate w along the ray, to generate perspective correct reflections + + w_begin = 1.0/w_begin; + w_end = 1.0/w_end; + + + float z_begin = vertex.z*w_begin; + float z_end = ray_end.z*w_end; + + vec2 line_begin = vp_line_begin/pixel_size; + vec2 line_dir = vp_line_dir/pixel_size; + float z_dir = z_end - z_begin; + float w_dir = w_end - w_begin; + + + // clip the line to the viewport edges + + float scale_max_x = min(1.0, 0.99 * (1.0 - vp_line_begin.x) / max(1e-5, vp_line_dir.x)); + float scale_max_y = min(1.0, 0.99 * (1.0 - vp_line_begin.y) / max(1e-5, vp_line_dir.y)); + float scale_min_x = min(1.0, 0.99 * vp_line_begin.x / max(1e-5, -vp_line_dir.x)); + float scale_min_y = min(1.0, 0.99 * vp_line_begin.y / max(1e-5, -vp_line_dir.y)); + float line_clip = min(scale_max_x, scale_max_y) * min(scale_min_x, scale_min_y); + line_dir *= line_clip; + z_dir *= line_clip; + w_dir *=line_clip; + + //clip z and w advance to line advance + vec2 line_advance = normalize(line_dir); //down to pixel + float step_size = length(line_advance)/length(line_dir); + float z_advance = z_dir*step_size; // adapt z advance to line advance + float w_advance = w_dir*step_size; // adapt w advance to line advance + + //make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice) + float advance_angle_adj = 1.0/max(abs(line_advance.x),abs(line_advance.y)); + line_advance*=advance_angle_adj; // adapt z advance to line advance + z_advance*=advance_angle_adj; + w_advance*=advance_angle_adj; + + vec2 pos = line_begin; + float z = z_begin; + float w = w_begin; + float z_from=z/w; + float z_to=z_from; + float depth; + vec2 prev_pos=pos; + + bool found=false; + + float steps_taken=0.0; + + for(int i=0;i<num_steps;i++) { + + pos+=line_advance; + z+=z_advance; + w+=w_advance; + + //convert to linear depth + + depth = texture(source_depth, pos*pixel_size).r * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else + depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); +#endif + depth=-depth; + + z_from = z_to; + z_to = z/w; + + if (depth>z_to) { + //if depth was surpassed + if (depth<=max(z_to,z_from)+depth_tolerance) { + //check the depth tolerance + found=true; + } + break; + } + + steps_taken+=1.0; + prev_pos=pos; + } + + + + + if (found) { + + float margin_blend=1.0; + + + vec2 margin = vec2((viewport_size.x+viewport_size.y)*0.5*0.05); //make a uniform margin + if (any(bvec4(lessThan(pos,-margin),greaterThan(pos,viewport_size+margin)))) { + //clip outside screen + margin + frag_color=vec4(0.0); + return; + } + + { + //blend fading out towards external margin + vec2 margin_grad = mix(pos-viewport_size,-pos,lessThan(pos,vec2(0.0))); + margin_blend = 1.0-smoothstep(0.0,margin.x,max(margin_grad.x,margin_grad.y)); + //margin_blend=1.0; + + } + + vec2 final_pos; + float grad; + grad=steps_taken/float(num_steps); + float initial_fade = curve_fade_in==0.0 ? 1.0 : pow(clamp(grad,0.0,1.0),curve_fade_in); + float fade = pow(clamp(1.0-grad,0.0,1.0),distance_fade)*initial_fade; + final_pos=pos; + + + + + + + +#ifdef REFLECT_ROUGHNESS + + + vec4 final_color; + //if roughness is enabled, do screen space cone tracing + if (roughness > 0.001) { + /////////////////////////////////////////////////////////////////////////////////////// + //use a blurred version (in consecutive mipmaps) of the screen to simulate roughness + + float gloss = 1.0-roughness; + float cone_angle = roughness * M_PI * 0.5; + vec2 cone_dir = final_pos - line_begin; + float cone_len = length(cone_dir); + cone_dir = normalize(cone_dir); //will be used normalized from now on + float max_mipmap = filter_mipmap_levels - 1.0; + float gloss_mult=gloss; + + float rem_alpha=1.0; + final_color = vec4(0.0); + + for(int i=0;i<7;i++) { + + float op_len = 2.0 * tan(cone_angle) * cone_len; //opposite side of iso triangle + float radius; + { + //fit to sphere inside cone (sphere ends at end of cone), something like this: + // ___ + // \O/ + // V + // + // as it avoids bleeding from beyond the reflection as much as possible. As a plus + // it also makes the rough reflection more elongated. + float a = op_len; + float h = cone_len; + float a2 = a * a; + float fh2 = 4.0f * h * h; + radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h); + } + + //find the place where screen must be sampled + vec2 sample_pos = ( line_begin + cone_dir * (cone_len - radius) ) * pixel_size; + //radius is in pixels, so it's natural that log2(radius) maps to the right mipmap for the amount of pixels + float mipmap = clamp( log2( radius ), 0.0, max_mipmap ); + + //mipmap = max(mipmap-1.0,0.0); + //do sampling + + vec4 sample_color; + { + sample_color = textureLod(source_diffuse,sample_pos,mipmap); + } + + //multiply by gloss + sample_color.rgb*=gloss_mult; + sample_color.a=gloss_mult; + + rem_alpha -= sample_color.a; + if(rem_alpha < 0.0) { + sample_color.rgb *= (1.0 - abs(rem_alpha)); + } + + final_color+=sample_color; + + if (final_color.a>=0.95) { + // This code of accumulating gloss and aborting on near one + // makes sense when you think of cone tracing. + // Think of it as if roughness was 0, then we could abort on the first + // iteration. For lesser roughness values, we need more iterations, but + // each needs to have less influence given the sphere is smaller + break; + } + + cone_len-=radius*2.0; //go to next (smaller) circle. + + gloss_mult*=gloss; + + + } + } else { + final_color = textureLod(source_diffuse,final_pos*pixel_size,0.0); + } + + frag_color = vec4(final_color.rgb,fade*margin_blend); + +#else + frag_color = vec4(textureLod(source_diffuse,final_pos*pixel_size,0.0).rgb,fade*margin_blend); +#endif + + + + } else { + frag_color = vec4(0.0,0.0,0.0,0.0); + } + + + +} + diff --git a/drivers/gles2/shaders/ssao.glsl b/drivers/gles2/shaders/ssao.glsl new file mode 100644 index 0000000000..219f0957e0 --- /dev/null +++ b/drivers/gles2/shaders/ssao.glsl @@ -0,0 +1,293 @@ +[vertex] + + +layout(location=0) in highp vec4 vertex_attrib; + +void main() { + + gl_Position = vertex_attrib; + gl_Position.z=1.0; +} + +[fragment] + +#define TWO_PI 6.283185307179586476925286766559 + +#ifdef SSAO_QUALITY_HIGH + +#define NUM_SAMPLES (80) + +#endif + +#ifdef SSAO_QUALITY_LOW + +#define NUM_SAMPLES (15) + +#endif + +#if !defined(SSAO_QUALITY_LOW) && !defined(SSAO_QUALITY_HIGH) + +#define NUM_SAMPLES (40) + +#endif + +// If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower +// miplevel to maintain reasonable spatial locality in the cache +// If this number is too small (< 3), too many taps will land in the same pixel, and we'll get bad variance that manifests as flashing. +// If it is too high (> 5), we'll get bad performance because we're not using the MIP levels effectively +#define LOG_MAX_OFFSET (3) + +// This must be less than or equal to the MAX_MIP_LEVEL defined in SSAO.cpp +#define MAX_MIP_LEVEL (4) + +// This is the number of turns around the circle that the spiral pattern makes. This should be prime to prevent +// taps from lining up. This particular choice was tuned for NUM_SAMPLES == 9 + +const int ROTATIONS[] = int[]( 1, 1, 2, 3, 2, 5, 2, 3, 2, +3, 3, 5, 5, 3, 4, 7, 5, 5, 7, +9, 8, 5, 5, 7, 7, 7, 8, 5, 8, +11, 12, 7, 10, 13, 8, 11, 8, 7, 14, +11, 11, 13, 12, 13, 19, 17, 13, 11, 18, +19, 11, 11, 14, 17, 21, 15, 16, 17, 18, +13, 17, 11, 17, 19, 18, 25, 18, 19, 19, +29, 21, 19, 27, 31, 29, 21, 18, 17, 29, +31, 31, 23, 18, 25, 26, 25, 23, 19, 34, +19, 27, 21, 25, 39, 29, 17, 21, 27 ); + +//#define NUM_SPIRAL_TURNS (7) +const int NUM_SPIRAL_TURNS = ROTATIONS[NUM_SAMPLES-1]; + +uniform sampler2D source_depth; //texunit:0 +uniform highp usampler2D source_depth_mipmaps; //texunit:1 +uniform sampler2D source_normal; //texunit:2 + +uniform ivec2 screen_size; +uniform float camera_z_far; +uniform float camera_z_near; + +uniform float intensity_div_r6; +uniform float radius; + +#ifdef ENABLE_RADIUS2 +uniform float intensity_div_r62; +uniform float radius2; +#endif + +uniform float bias; +uniform float proj_scale; + +layout(location = 0) out float visibility; + +uniform vec4 proj_info; + +vec3 reconstructCSPosition(vec2 S, float z) { +#ifdef USE_ORTHOGONAL_PROJECTION + return vec3((S.xy * proj_info.xy + proj_info.zw), z); +#else + return vec3((S.xy * proj_info.xy + proj_info.zw) * z, z); + +#endif +} + +vec3 getPosition(ivec2 ssP) { + vec3 P; + P.z = texelFetch(source_depth, ssP, 0).r; + + P.z = P.z * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + P.z = ((P.z + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else + P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near)); +#endif + P.z = -P.z; + + // Offset to pixel center + P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z); + return P; +} + +/** Reconstructs screen-space unit normal from screen-space position */ +vec3 reconstructCSFaceNormal(vec3 C) { + return normalize(cross(dFdy(C), dFdx(C))); +} + + + +/** Returns a unit vector and a screen-space radius for the tap on a unit disk (the caller should scale by the actual disk radius) */ +vec2 tapLocation(int sampleNumber, float spinAngle, out float ssR){ + // Radius relative to ssR + float alpha = (float(sampleNumber) + 0.5) * (1.0 / float(NUM_SAMPLES)); + float angle = alpha * (float(NUM_SPIRAL_TURNS) * 6.28) + spinAngle; + + ssR = alpha; + return vec2(cos(angle), sin(angle)); +} + + +/** Read the camera-space position of the point at screen-space pixel ssP + unitOffset * ssR. Assumes length(unitOffset) == 1 */ +vec3 getOffsetPosition(ivec2 ssC, vec2 unitOffset, float ssR) { + // Derivation: + // mipLevel = floor(log(ssR / MAX_OFFSET)); + int mipLevel = clamp(int(floor(log2(ssR))) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL); + + ivec2 ssP = ivec2(ssR * unitOffset) + ssC; + + vec3 P; + + // We need to divide by 2^mipLevel to read the appropriately scaled coordinate from a MIP-map. + // Manually clamp to the texture size because texelFetch bypasses the texture unit + ivec2 mipP = clamp(ssP >> mipLevel, ivec2(0), (screen_size >> mipLevel) - ivec2(1)); + + + if (mipLevel < 1) { + //read from depth buffer + P.z = texelFetch(source_depth, mipP, 0).r; + P.z = P.z * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + P.z = ((P.z + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else + P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near)); + +#endif + P.z = -P.z; + + } else { + //read from mipmaps + uint d = texelFetch(source_depth_mipmaps, mipP, mipLevel-1).r; + P.z = -(float(d)/65535.0)*camera_z_far; + } + + + // Offset to pixel center + P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z); + + return P; +} + + + +/** Compute the occlusion due to sample with index \a i about the pixel at \a ssC that corresponds + to camera-space point \a C with unit normal \a n_C, using maximum screen-space sampling radius \a ssDiskRadius + + Note that units of H() in the HPG12 paper are meters, not + unitless. The whole falloff/sampling function is therefore + unitless. In this implementation, we factor out (9 / radius). + + Four versions of the falloff function are implemented below +*/ +float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius,in float p_radius, in int tapIndex, in float randomPatternRotationAngle) { + // Offset on the unit disk, spun for this pixel + float ssR; + vec2 unitOffset = tapLocation(tapIndex, randomPatternRotationAngle, ssR); + ssR *= ssDiskRadius; + + // The occluding point in camera space + vec3 Q = getOffsetPosition(ssC, unitOffset, ssR); + + vec3 v = Q - C; + + float vv = dot(v, v); + float vn = dot(v, n_C); + + const float epsilon = 0.01; + float radius2 = p_radius*p_radius; + + // A: From the HPG12 paper + // Note large epsilon to avoid overdarkening within cracks + //return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6; + + // B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended] + float f=max(radius2 - vv, 0.0); + return f * f * f * max((vn - bias) / (epsilon + vv), 0.0); + + // C: Medium contrast (which looks better at high radii), no division. Note that the + // contribution still falls off with radius^2, but we've adjusted the rate in a way that is + // more computationally efficient and happens to be aesthetically pleasing. + // return 4.0 * max(1.0 - vv * invRadius2, 0.0) * max(vn - bias, 0.0); + + // D: Low contrast, no division operation + // return 2.0 * float(vv < radius * radius) * max(vn - bias, 0.0); +} + + + +void main() { + + + // Pixel being shaded + ivec2 ssC = ivec2(gl_FragCoord.xy); + + // World space point being shaded + vec3 C = getPosition(ssC); + +/* if (C.z <= -camera_z_far*0.999) { + // We're on the skybox + visibility=1.0; + return; + }*/ + + //visibility=-C.z/camera_z_far; + //return; +#if 0 + vec3 n_C = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0; +#else + vec3 n_C = reconstructCSFaceNormal(C); + n_C = -n_C; +#endif + + // Hash function used in the HPG12 AlchemyAO paper + float randomPatternRotationAngle = mod(float((3 * ssC.x ^ ssC.y + ssC.x * ssC.y) * 10), TWO_PI); + + // Reconstruct normals from positions. These will lead to 1-pixel black lines + // at depth discontinuities, however the blur will wipe those out so they are not visible + // in the final image. + + // Choose the screen-space sample radius + // proportional to the projected area of the sphere +#ifdef USE_ORTHOGONAL_PROJECTION + float ssDiskRadius = -proj_scale * radius; +#else + float ssDiskRadius = -proj_scale * radius / C.z; +#endif + float sum = 0.0; + for (int i = 0; i < NUM_SAMPLES; ++i) { + sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius,i, randomPatternRotationAngle); + } + + float A = max(0.0, 1.0 - sum * intensity_div_r6 * (5.0 / float(NUM_SAMPLES))); + +#ifdef ENABLE_RADIUS2 + + //go again for radius2 + randomPatternRotationAngle = mod(float((5 * ssC.x ^ ssC.y + ssC.x * ssC.y) * 11), TWO_PI); + + // Reconstruct normals from positions. These will lead to 1-pixel black lines + // at depth discontinuities, however the blur will wipe those out so they are not visible + // in the final image. + + // Choose the screen-space sample radius + // proportional to the projected area of the sphere + ssDiskRadius = -proj_scale * radius2 / C.z; + + sum = 0.0; + for (int i = 0; i < NUM_SAMPLES; ++i) { + sum += sampleAO(ssC, C, n_C, ssDiskRadius,radius2, i, randomPatternRotationAngle); + } + + A= min(A,max(0.0, 1.0 - sum * intensity_div_r62 * (5.0 / float(NUM_SAMPLES)))); +#endif + // Bilateral box-filter over a quad for free, respecting depth edges + // (the difference that this makes is subtle) + if (abs(dFdx(C.z)) < 0.02) { + A -= dFdx(A) * (float(ssC.x & 1) - 0.5); + } + if (abs(dFdy(C.z)) < 0.02) { + A -= dFdy(A) * (float(ssC.y & 1) - 0.5); + } + + visibility = A; + +} + + + diff --git a/drivers/gles2/shaders/ssao_blur.glsl b/drivers/gles2/shaders/ssao_blur.glsl new file mode 100644 index 0000000000..472dc21acf --- /dev/null +++ b/drivers/gles2/shaders/ssao_blur.glsl @@ -0,0 +1,124 @@ +[vertex] + + +layout(location=0) in highp vec4 vertex_attrib; + + +void main() { + + gl_Position = vertex_attrib; + gl_Position.z=1.0; +} + +[fragment] + + +uniform sampler2D source_ssao; //texunit:0 +uniform sampler2D source_depth; //texunit:1 +uniform sampler2D source_normal; //texunit:3 + + +layout(location = 0) out float visibility; + + +////////////////////////////////////////////////////////////////////////////////////////////// +// Tunable Parameters: + +/** Increase to make depth edges crisper. Decrease to reduce flicker. */ +uniform float edge_sharpness; + +/** Step in 2-pixel intervals since we already blurred against neighbors in the + first AO pass. This constant can be increased while R decreases to improve + performance at the expense of some dithering artifacts. + + Morgan found that a scale of 3 left a 1-pixel checkerboard grid that was + unobjectionable after shading was applied but eliminated most temporal incoherence + from using small numbers of sample taps. + */ + +uniform int filter_scale; + +/** Filter radius in pixels. This will be multiplied by SCALE. */ +#define R (4) + + +////////////////////////////////////////////////////////////////////////////////////////////// + + +// Gaussian coefficients +const float gaussian[R + 1] = +// float[](0.356642, 0.239400, 0.072410, 0.009869); +// float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // stddev = 1.0 + float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // stddev = 2.0 +// float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0 + +/** (1, 0) or (0, 1)*/ +uniform ivec2 axis; + +uniform float camera_z_far; +uniform float camera_z_near; + +uniform ivec2 screen_size; + +void main() { + + ivec2 ssC = ivec2(gl_FragCoord.xy); + + float depth = texelFetch(source_depth, ssC, 0).r; + //vec3 normal = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0; + + depth = depth * 2.0 - 1.0; + depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); + + float depth_divide = 1.0 / camera_z_far; + +// depth*=depth_divide; + + /* + if (depth > camera_z_far*0.999) { + discard;//skybox + } + */ + + float sum = texelFetch(source_ssao, ssC, 0).r; + + // Base weight for depth falloff. Increase this for more blurriness, + // decrease it for better edge discrimination + float BASE = gaussian[0]; + float totalWeight = BASE; + sum *= totalWeight; + + ivec2 clamp_limit = screen_size - ivec2(1); + + for (int r = -R; r <= R; ++r) { + // We already handled the zero case above. This loop should be unrolled and the static branch optimized out, + // so the IF statement has no runtime cost + if (r != 0) { + + ivec2 ppos = ssC + axis * (r * filter_scale); + float value = texelFetch(source_ssao, clamp(ppos,ivec2(0),clamp_limit), 0).r; + ivec2 rpos = clamp(ppos,ivec2(0),clamp_limit); + float temp_depth = texelFetch(source_depth, rpos, 0).r; + //vec3 temp_normal = texelFetch(source_normal, rpos, 0).rgb * 2.0 - 1.0; + + temp_depth = temp_depth * 2.0 - 1.0; + temp_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - temp_depth * (camera_z_far - camera_z_near)); +// temp_depth *= depth_divide; + + // spatial domain: offset gaussian tap + float weight = 0.3 + gaussian[abs(r)]; + //weight *= max(0.0,dot(temp_normal,normal)); + + // range domain (the "bilateral" weight). As depth difference increases, decrease weight. + weight *= max(0.0, 1.0 + - edge_sharpness * abs(temp_depth - depth) + ); + + sum += value * weight; + totalWeight += weight; + } + } + + const float epsilon = 0.0001; + visibility = sum / (totalWeight + epsilon); +} diff --git a/drivers/gles2/shaders/ssao_minify.glsl b/drivers/gles2/shaders/ssao_minify.glsl new file mode 100644 index 0000000000..647c762438 --- /dev/null +++ b/drivers/gles2/shaders/ssao_minify.glsl @@ -0,0 +1,59 @@ +[vertex] + + +layout(location=0) in highp vec4 vertex_attrib; + +void main() { + + gl_Position = vertex_attrib; +} + +[fragment] + + +#ifdef MINIFY_START + +#define SDEPTH_TYPE highp sampler2D +uniform float camera_z_far; +uniform float camera_z_near; + +#else + +#define SDEPTH_TYPE mediump usampler2D + +#endif + +uniform SDEPTH_TYPE source_depth; //texunit:0 + +uniform ivec2 from_size; +uniform int source_mipmap; + +layout(location = 0) out mediump uint depth; + +void main() { + + + ivec2 ssP = ivec2(gl_FragCoord.xy); + + // Rotated grid subsampling to avoid XY directional bias or Z precision bias while downsampling. + // On DX9, the bit-and can be implemented with floating-point modulo + +#ifdef MINIFY_START + float fdepth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r; + fdepth = fdepth * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + fdepth = ((fdepth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else + fdepth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - fdepth * (camera_z_far - camera_z_near)); +#endif + fdepth /= camera_z_far; + depth = uint(clamp(fdepth*65535.0,0.0,65535.0)); + +#else + depth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r; +#endif + + +} + + diff --git a/drivers/gles2/shaders/subsurf_scattering.glsl b/drivers/gles2/shaders/subsurf_scattering.glsl new file mode 100644 index 0000000000..fc66d66198 --- /dev/null +++ b/drivers/gles2/shaders/subsurf_scattering.glsl @@ -0,0 +1,192 @@ +[vertex] + + +layout(location=0) in highp vec4 vertex_attrib; +layout(location=4) in vec2 uv_in; + +out vec2 uv_interp; + + +void main() { + + uv_interp = uv_in; + gl_Position = vertex_attrib; +} + +[fragment] + +//#define QUALIFIER uniform // some guy on the interweb says it may be faster with this +#define QUALIFIER const + +#ifdef USE_25_SAMPLES + +const int kernel_size=25; +QUALIFIER vec2 kernel[25] = vec2[] ( + vec2(0.530605, 0.0), + vec2(0.000973794, -3.0), + vec2(0.00333804, -2.52083), + vec2(0.00500364, -2.08333), + vec2(0.00700976, -1.6875), + vec2(0.0094389, -1.33333), + vec2(0.0128496, -1.02083), + vec2(0.017924, -0.75), + vec2(0.0263642, -0.520833), + vec2(0.0410172, -0.333333), + vec2(0.0493588, -0.1875), + vec2(0.0402784, -0.0833333), + vec2(0.0211412, -0.0208333), + vec2(0.0211412, 0.0208333), + vec2(0.0402784, 0.0833333), + vec2(0.0493588, 0.1875), + vec2(0.0410172, 0.333333), + vec2(0.0263642, 0.520833), + vec2(0.017924, 0.75), + vec2(0.0128496, 1.02083), + vec2(0.0094389, 1.33333), + vec2(0.00700976, 1.6875), + vec2(0.00500364, 2.08333), + vec2(0.00333804, 2.52083), + vec2(0.000973794, 3.0) +); + +#endif //USE_25_SAMPLES + +#ifdef USE_17_SAMPLES + +const int kernel_size=17; + +QUALIFIER vec2 kernel[17] = vec2[]( + vec2(0.536343, 0.0), + vec2(0.00317394, -2.0), + vec2(0.0100386, -1.53125), + vec2(0.0144609, -1.125), + vec2(0.0216301, -0.78125), + vec2(0.0347317, -0.5), + vec2(0.0571056, -0.28125), + vec2(0.0582416, -0.125), + vec2(0.0324462, -0.03125), + vec2(0.0324462, 0.03125), + vec2(0.0582416, 0.125), + vec2(0.0571056, 0.28125), + vec2(0.0347317, 0.5), + vec2(0.0216301, 0.78125), + vec2(0.0144609, 1.125), + vec2(0.0100386, 1.53125), + vec2(0.00317394,2.0) +); + +#endif //USE_17_SAMPLES + + +#ifdef USE_11_SAMPLES + +const int kernel_size=11; + +QUALIFIER vec2 kernel[11] = vec2[]( + vec2(0.560479, 0.0), + vec2(0.00471691, -2.0), + vec2(0.0192831, -1.28), + vec2(0.03639, -0.72), + vec2(0.0821904, -0.32), + vec2(0.0771802, -0.08), + vec2(0.0771802, 0.08), + vec2(0.0821904, 0.32), + vec2(0.03639, 0.72), + vec2(0.0192831, 1.28), + vec2(0.00471691,2.0) +); + +#endif //USE_11_SAMPLES + + + +uniform float max_radius; +uniform float camera_z_far; +uniform float camera_z_near; +uniform float unit_size; +uniform vec2 dir; +in vec2 uv_interp; + +uniform sampler2D source_diffuse; //texunit:0 +uniform sampler2D source_sss; //texunit:1 +uniform sampler2D source_depth; //texunit:2 + +layout(location = 0) out vec4 frag_color; + +void main() { + + float strength = texture(source_sss,uv_interp).r; + strength*=strength; //stored as sqrt + + // Fetch color of current pixel: + vec4 base_color = texture(source_diffuse, uv_interp); + + + if (strength>0.0) { + + + // Fetch linear depth of current pixel: + float depth = texture(source_depth, uv_interp).r * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; + float scale = unit_size; //remember depth is negative by default in OpenGL +#else + depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); + float scale = unit_size / depth; //remember depth is negative by default in OpenGL +#endif + + + + // Calculate the final step to fetch the surrounding pixels: + vec2 step = max_radius * scale * dir; + step *= strength; // Modulate it using the alpha channel. + step *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3. + + // Accumulate the center sample: + vec3 color_accum = base_color.rgb; + color_accum *= kernel[0].x; +#ifdef ENABLE_STRENGTH_WEIGHTING + float color_weight = kernel[0].x; +#endif + + // Accumulate the other samples: + for (int i = 1; i < kernel_size; i++) { + // Fetch color and depth for current sample: + vec2 offset = uv_interp + kernel[i].y * step; + vec3 color = texture(source_diffuse, offset).rgb; + +#ifdef ENABLE_FOLLOW_SURFACE + // If the difference in depth is huge, we lerp color back to "colorM": + float depth_cmp = texture(source_depth, offset).r *2.0 - 1.0; + +#ifdef USE_ORTHOGONAL_PROJECTION + depth_cmp = ((depth_cmp + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else + depth_cmp = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth_cmp * (camera_z_far - camera_z_near)); +#endif + + float s = clamp(300.0f * scale * + max_radius * abs(depth - depth_cmp),0.0,1.0); + color = mix(color, base_color.rgb, s); +#endif + + // Accumulate: + color*=kernel[i].x; + +#ifdef ENABLE_STRENGTH_WEIGHTING + float color_s = texture(source_sss, offset).r; + color_weight+=color_s * kernel[i].x; + color*=color_s; +#endif + color_accum += color; + + } + +#ifdef ENABLE_STRENGTH_WEIGHTING + color_accum/=color_weight; +#endif + frag_color = vec4(color_accum,base_color.a); //keep alpha (used for SSAO) + } else { + frag_color = base_color; + } +} diff --git a/drivers/gles2/shaders/tonemap.glsl b/drivers/gles2/shaders/tonemap.glsl new file mode 100644 index 0000000000..2f671158b2 --- /dev/null +++ b/drivers/gles2/shaders/tonemap.glsl @@ -0,0 +1,323 @@ +[vertex] + + +layout(location=0) in highp vec4 vertex_attrib; +layout(location=4) in vec2 uv_in; + +out vec2 uv_interp; + +void main() { + + gl_Position = vertex_attrib; + uv_interp = uv_in; +#ifdef V_FLIP + uv_interp.y = 1.0-uv_interp.y; +#endif + +} + +[fragment] + +#if !defined(GLES_OVER_GL) +precision mediump float; +#endif + + +in vec2 uv_interp; + +uniform highp sampler2D source; //texunit:0 + +uniform float exposure; +uniform float white; + +#ifdef USE_AUTO_EXPOSURE + +uniform highp sampler2D source_auto_exposure; //texunit:1 +uniform highp float auto_exposure_grey; + +#endif + +#if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7) + +uniform highp sampler2D source_glow; //texunit:2 +uniform highp float glow_intensity; + +#endif + +#ifdef USE_BCS + +uniform vec3 bcs; + +#endif + +#ifdef USE_COLOR_CORRECTION + +uniform sampler2D color_correction; //texunit:3 + +#endif + + +layout(location = 0) out vec4 frag_color; + +#ifdef USE_GLOW_FILTER_BICUBIC + +// w0, w1, w2, and w3 are the four cubic B-spline basis functions +float w0(float a) +{ + return (1.0/6.0)*(a*(a*(-a + 3.0) - 3.0) + 1.0); +} + +float w1(float a) +{ + return (1.0/6.0)*(a*a*(3.0*a - 6.0) + 4.0); +} + +float w2(float a) +{ + return (1.0/6.0)*(a*(a*(-3.0*a + 3.0) + 3.0) + 1.0); +} + +float w3(float a) +{ + return (1.0/6.0)*(a*a*a); +} + +// g0 and g1 are the two amplitude functions +float g0(float a) +{ + return w0(a) + w1(a); +} + +float g1(float a) +{ + return w2(a) + w3(a); +} + +// h0 and h1 are the two offset functions +float h0(float a) +{ + return -1.0 + w1(a) / (w0(a) + w1(a)); +} + +float h1(float a) +{ + return 1.0 + w3(a) / (w2(a) + w3(a)); +} + +uniform ivec2 glow_texture_size; + +vec4 texture2D_bicubic(sampler2D tex, vec2 uv,int p_lod) +{ + float lod=float(p_lod); + vec2 tex_size = vec2(glow_texture_size >> p_lod); + vec2 pixel_size =1.0/tex_size; + uv = uv*tex_size + 0.5; + vec2 iuv = floor( uv ); + vec2 fuv = fract( uv ); + + float g0x = g0(fuv.x); + float g1x = g1(fuv.x); + float h0x = h0(fuv.x); + float h1x = h1(fuv.x); + float h0y = h0(fuv.y); + float h1y = h1(fuv.y); + + vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - 0.5) * pixel_size; + vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - 0.5) * pixel_size; + vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - 0.5) * pixel_size; + vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - 0.5) * pixel_size; + + return g0(fuv.y) * (g0x * textureLod(tex, p0,lod) + + g1x * textureLod(tex, p1,lod)) + + g1(fuv.y) * (g0x * textureLod(tex, p2,lod) + + g1x * textureLod(tex, p3,lod)); +} + + + +#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) texture2D_bicubic(m_tex,m_uv,m_lod) + +#else + +#define GLOW_TEXTURE_SAMPLE(m_tex,m_uv,m_lod) textureLod(m_tex,m_uv,float(m_lod)) + +#endif + + +vec3 tonemap_filmic(vec3 color,float white) { + + float A = 0.15; + float B = 0.50; + float C = 0.10; + float D = 0.20; + float E = 0.02; + float F = 0.30; + float W = 11.2; + + vec3 coltn = ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F; + float whitetn = ((white*(A*white+C*B)+D*E)/(white*(A*white+B)+D*F))-E/F; + + return coltn/whitetn; + +} + +vec3 tonemap_aces(vec3 color) { + float a = 2.51f; + float b = 0.03f; + float c = 2.43f; + float d = 0.59f; + float e = 0.14f; + return color = clamp((color*(a*color+b))/(color*(c*color+d)+e),vec3(0.0),vec3(1.0)); +} + +vec3 tonemap_reindhart(vec3 color,float white) { + + return ( color * ( 1.0 + ( color / ( white) ) ) ) / ( 1.0 + color ); +} + +void main() { + + vec4 color = textureLod(source, uv_interp, 0.0); + +#ifdef USE_AUTO_EXPOSURE + + color/=texelFetch(source_auto_exposure,ivec2(0,0),0).r/auto_exposure_grey; +#endif + + color*=exposure; + +#if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7) +#define USING_GLOW +#endif + +#if defined(USING_GLOW) + vec3 glow = vec3(0.0); + +#ifdef USE_GLOW_LEVEL1 + + glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,1).rgb; +#endif + +#ifdef USE_GLOW_LEVEL2 + glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,2).rgb; +#endif + +#ifdef USE_GLOW_LEVEL3 + glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,3).rgb; +#endif + +#ifdef USE_GLOW_LEVEL4 + glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,4).rgb; +#endif + +#ifdef USE_GLOW_LEVEL5 + glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,5).rgb; +#endif + +#ifdef USE_GLOW_LEVEL6 + glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,6).rgb; +#endif + +#ifdef USE_GLOW_LEVEL7 + glow+=GLOW_TEXTURE_SAMPLE(source_glow,uv_interp,7).rgb; +#endif + + + glow *= glow_intensity; + +#endif + + +#ifdef USE_REINDHART_TONEMAPPER + + color.rgb = tonemap_reindhart(color.rgb,white); + +# if defined(USING_GLOW) + glow = tonemap_reindhart(glow,white); +# endif + +#endif + +#ifdef USE_FILMIC_TONEMAPPER + + color.rgb = tonemap_filmic(color.rgb,white); + +# if defined(USING_GLOW) + glow = tonemap_filmic(glow,white); +# endif + +#endif + +#ifdef USE_ACES_TONEMAPPER + + color.rgb = tonemap_aces(color.rgb); + +# if defined(USING_GLOW) + glow = tonemap_aces(glow); +# endif + +#endif + + //regular Linear -> SRGB conversion + vec3 a = vec3(0.055); + color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308))); + +#if defined(USING_GLOW) + glow = mix( (vec3(1.0)+a)*pow(glow,vec3(1.0/2.4))-a , 12.92*glow , lessThan(glow,vec3(0.0031308))); +#endif + +//glow needs to be added in SRGB space (together with image space effects) + + color.rgb = clamp(color.rgb,0.0,1.0); + +#if defined(USING_GLOW) + glow = clamp(glow,0.0,1.0); +#endif + +#ifdef USE_GLOW_REPLACE + + color.rgb = glow; + +#endif + +#ifdef USE_GLOW_SCREEN + + color.rgb = max((color.rgb + glow) - (color.rgb * glow), vec3(0.0)); + +#endif + +#ifdef USE_GLOW_SOFTLIGHT + + { + + glow = (glow * 0.5) + 0.5; + color.r = (glow.r <= 0.5) ? (color.r - (1.0 - 2.0 * glow.r) * color.r * (1.0 - color.r)) : (((glow.r > 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r))); + color.g = (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g))); + color.b = (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b))); + } + +#endif + +#if defined(USING_GLOW) && !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) + //additive + color.rgb+=glow; +#endif + +#ifdef USE_BCS + + color.rgb = mix(vec3(0.0),color.rgb,bcs.x); + color.rgb = mix(vec3(0.5),color.rgb,bcs.y); + color.rgb = mix(vec3(dot(vec3(1.0),color.rgb)*0.33333),color.rgb,bcs.z); + +#endif + +#ifdef USE_COLOR_CORRECTION + + color.r = texture(color_correction,vec2(color.r,0.0)).r; + color.g = texture(color_correction,vec2(color.g,0.0)).g; + color.b = texture(color_correction,vec2(color.b,0.0)).b; +#endif + + + frag_color=vec4(color.rgb,1.0); +} diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index d4b6c8577e..c33fdaa355 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -566,7 +566,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur } else { - _draw_generic(GL_LINES, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); + _draw_generic(GL_LINE_STRIP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); } #ifdef GLES_OVER_GL @@ -1042,7 +1042,7 @@ void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) { glEnable(GL_BLEND); } -void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light) { +void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_transform) { Item *current_clip = NULL; RasterizerStorageGLES3::Shader *shader_cache = NULL; diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index 9f1a9466f1..1dc17f98d5 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -129,7 +129,7 @@ public: _FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip); _FORCE_INLINE_ void _copy_texscreen(const Rect2 &p_rect); - virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light); + virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_transform); virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow); virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache); diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index b43deab58f..ca39d9f966 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -160,29 +160,31 @@ void RasterizerGLES3::initialize() { "Fatal error: Insufficient OpenGL / GLES driver support"); } -#ifdef __APPLE__ -// FIXME glDebugMessageCallbackARB does not seem to work on Mac OS X and opengl 3, this may be an issue with our opengl canvas.. -#else if (OS::get_singleton()->is_stdout_verbose()) { - glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB); - glDebugMessageCallbackARB(_gl_debug_print, NULL); - glEnable(_EXT_DEBUG_OUTPUT); + if (GLAD_GL_ARB_debug_output) { + glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + glDebugMessageCallbackARB(_gl_debug_print, NULL); + glEnable(_EXT_DEBUG_OUTPUT); + } else { + print_line("OpenGL debugging not supported!"); + } } -#endif #endif // GLAD_ENABLED /* // For debugging - glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_ERROR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); - glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); - glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); - glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PORTABILITY_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); - glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PERFORMANCE_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); - glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_OTHER_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); - glDebugMessageInsertARB( - GL_DEBUG_SOURCE_API_ARB, - GL_DEBUG_TYPE_OTHER_ARB, 1, - GL_DEBUG_SEVERITY_HIGH_ARB,5, "hello"); + if (GLAD_GL_ARB_debug_output) { + glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_ERROR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); + glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); + glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); + glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PORTABILITY_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); + glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PERFORMANCE_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); + glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_OTHER_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); + glDebugMessageInsertARB( + GL_DEBUG_SOURCE_API_ARB, + GL_DEBUG_TYPE_OTHER_ARB, 1, + GL_DEBUG_SEVERITY_HIGH_ARB,5, "hello"); + } */ const GLubyte *renderer = glGetString(GL_RENDERER); @@ -413,4 +415,5 @@ RasterizerGLES3::~RasterizerGLES3() { memdelete(storage); memdelete(canvas); + memdelete(scene); } diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 7c053e8f60..5b6b3d44f2 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -2085,9 +2085,9 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ case RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MUL: { glBlendEquation(GL_FUNC_ADD); if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_DST_ALPHA, GL_ZERO); } else { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ZERO, GL_ONE); } } break; @@ -2356,8 +2356,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy) { - if (!p_sky) - return; + ERR_FAIL_COND(!p_sky); RasterizerStorageGLES3::Texture *tex = storage->texture_owner.getornull(p_sky->panorama); @@ -4337,7 +4336,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo); //switch to alpha fbo for sky, only diffuse/ambient matters */ - _draw_sky(sky, p_cam_projection, p_cam_transform, false, env->sky_custom_fov, env->bg_energy); + if (sky && sky->panorama.is_valid()) + _draw_sky(sky, p_cam_projection, p_cam_transform, false, env->sky_custom_fov, env->bg_energy); } //_render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting,true); @@ -5118,3 +5118,23 @@ void RasterizerSceneGLES3::finalize() { RasterizerSceneGLES3::RasterizerSceneGLES3() { } + +RasterizerSceneGLES3::~RasterizerSceneGLES3() { + + memdelete(default_material.get_data()); + memdelete(default_material_twosided.get_data()); + memdelete(default_shader.get_data()); + memdelete(default_shader_twosided.get_data()); + + memdelete(default_worldcoord_material.get_data()); + memdelete(default_worldcoord_material_twosided.get_data()); + memdelete(default_worldcoord_shader.get_data()); + memdelete(default_worldcoord_shader_twosided.get_data()); + + memdelete(default_overdraw_material.get_data()); + memdelete(default_overdraw_shader.get_data()); + + memfree(state.spot_array_tmp); + memfree(state.omni_array_tmp); + memfree(state.reflection_array_tmp); +} diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 1b99e119ce..a6faeef473 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -852,6 +852,7 @@ public: void initialize(); void finalize(); RasterizerSceneGLES3(); + ~RasterizerSceneGLES3(); }; #endif // RASTERIZERSCENEGLES3_H diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 0fc095a868..a287dca1ed 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -908,7 +908,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSi return Ref<Image>(img); #else - ERR_EXPLAIN("Sorry, It's not posible to obtain images back in OpenGL ES"); + ERR_EXPLAIN("Sorry, It's not possible to obtain images back in OpenGL ES"); return Ref<Image>(); #endif } diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index e90245b300..5dddb1a900 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -37,183 +37,215 @@ #include "os/os.h" #include "project_settings.h" -void pa_state_cb(pa_context *c, void *userdata) { - pa_context_state_t state; - int *pa_ready = (int *)userdata; +void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) { + AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; - state = pa_context_get_state(c); - switch (state) { - case PA_CONTEXT_FAILED: + switch (pa_context_get_state(c)) { case PA_CONTEXT_TERMINATED: - *pa_ready = 2; + case PA_CONTEXT_FAILED: + ad->pa_ready = -1; break; case PA_CONTEXT_READY: - *pa_ready = 1; + ad->pa_ready = 1; break; } } -void sink_info_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata) { - unsigned int *channels = (unsigned int *)userdata; +void AudioDriverPulseAudio::pa_sink_info_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata) { + AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; // If eol is set to a positive number, you're at the end of the list if (eol > 0) { return; } - *channels = l->channel_map.channels; + ad->pa_channels = l->channel_map.channels; + ad->pa_status++; } -void server_info_cb(pa_context *c, const pa_server_info *i, void *userdata) { - char *default_output = (char *)userdata; +void AudioDriverPulseAudio::pa_server_info_cb(pa_context *c, const pa_server_info *i, void *userdata) { + AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; - strncpy(default_output, i->default_sink_name, 1024); + ad->default_device = i->default_sink_name; + ad->pa_status++; } -static unsigned int detect_channels() { - - pa_mainloop *pa_ml; - pa_mainloop_api *pa_mlapi; - pa_operation *pa_op; - pa_context *pa_ctx; - - int state = 0; - int pa_ready = 0; - - char default_output[1024]; - unsigned int channels = 2; +void AudioDriverPulseAudio::detect_channels() { - pa_ml = pa_mainloop_new(); - pa_mlapi = pa_mainloop_get_api(pa_ml); - pa_ctx = pa_context_new(pa_mlapi, "Godot"); + pa_channels = 2; - int ret = pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL); - if (ret < 0) { - pa_context_unref(pa_ctx); - pa_mainloop_free(pa_ml); - - return 2; - } - - pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready); + if (device_name == "Default") { + // Get the default output device name + pa_status = 0; + pa_operation *pa_op = pa_context_get_server_info(pa_ctx, &AudioDriverPulseAudio::pa_server_info_cb, (void *)this); + if (pa_op) { + while (pa_status == 0) { + int ret = pa_mainloop_iterate(pa_ml, 1, NULL); + if (ret < 0) { + ERR_PRINT("pa_mainloop_iterate error"); + } + } - // Wait until the pa server is ready - while (pa_ready == 0) { - pa_mainloop_iterate(pa_ml, 1, NULL); + pa_operation_unref(pa_op); + } else { + ERR_PRINT("pa_context_get_server_info error"); + } } - // Check if there was an error connecting to the pa server - if (pa_ready == 2) { - pa_context_disconnect(pa_ctx); - pa_context_unref(pa_ctx); - pa_mainloop_free(pa_ml); - - return 2; + char device[1024]; + if (device_name == "Default") { + strcpy(device, default_device.utf8().get_data()); + } else { + strcpy(device, device_name.utf8().get_data()); } - // Get the default output device name - pa_op = pa_context_get_server_info(pa_ctx, &server_info_cb, (void *)default_output); + // Now using the device name get the amount of channels + pa_status = 0; + pa_operation *pa_op = pa_context_get_sink_info_by_name(pa_ctx, device, &AudioDriverPulseAudio::pa_sink_info_cb, (void *)this); if (pa_op) { - while (pa_operation_get_state(pa_op) == PA_OPERATION_RUNNING) { - ret = pa_mainloop_iterate(pa_ml, 1, NULL); + while (pa_status == 0) { + int ret = pa_mainloop_iterate(pa_ml, 1, NULL); if (ret < 0) { ERR_PRINT("pa_mainloop_iterate error"); } } pa_operation_unref(pa_op); - - // Now using the device name get the amount of channels - pa_op = pa_context_get_sink_info_by_name(pa_ctx, default_output, &sink_info_cb, (void *)&channels); - if (pa_op) { - while (pa_operation_get_state(pa_op) == PA_OPERATION_RUNNING) { - ret = pa_mainloop_iterate(pa_ml, 1, NULL); - if (ret < 0) { - ERR_PRINT("pa_mainloop_iterate error"); - } - } - - pa_operation_unref(pa_op); - } else { - ERR_PRINT("pa_context_get_sink_info_by_name error"); - } } else { - ERR_PRINT("pa_context_get_server_info error"); + ERR_PRINT("pa_context_get_sink_info_by_name error"); } - - pa_context_disconnect(pa_ctx); - pa_context_unref(pa_ctx); - pa_mainloop_free(pa_ml); - - return channels; } -Error AudioDriverPulseAudio::init() { +Error AudioDriverPulseAudio::init_device() { - active = false; - thread_exited = false; - exit_thread = false; + // If there is a specified device check that it is really present + if (device_name != "Default") { + Array list = get_device_list(); + if (list.find(device_name) == -1) { + device_name = "Default"; + new_device = "Default"; + } + } - mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE); - channels = detect_channels(); + // Detect the amount of channels PulseAudio is using + // Note: If using an even amount of channels (2, 4, etc) channels and pa_channels will be equal, + // if not then pa_channels will have the real amount of channels PulseAudio is using and channels + // will have the amount of channels Godot is using (in this case it's pa_channels + 1) + detect_channels(); + switch (pa_channels) { + case 1: // Mono + case 3: // Surround 2.1 + case 5: // Surround 5.0 + case 7: // Surround 7.0 + channels = pa_channels + 1; + break; - switch (channels) { case 2: // Stereo - case 4: // Surround 3.1 + case 4: // Surround 4.0 case 6: // Surround 5.1 case 8: // Surround 7.1 + channels = pa_channels; break; default: - ERR_PRINTS("PulseAudio: Unsupported number of channels: " + itos(channels)); + ERR_PRINTS("PulseAudio: Unsupported number of channels: " + itos(pa_channels)); ERR_FAIL_V(ERR_CANT_OPEN); break; } pa_sample_spec spec; spec.format = PA_SAMPLE_S16LE; - spec.channels = channels; + spec.channels = pa_channels; spec.rate = mix_rate; int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY); buffer_frames = closest_power_of_2(latency * mix_rate / 1000); - buffer_size = buffer_frames * channels; + pa_buffer_size = buffer_frames * pa_channels; if (OS::get_singleton()->is_stdout_verbose()) { - print_line("PulseAudio: detected " + itos(channels) + " channels"); + print_line("PulseAudio: detected " + itos(pa_channels) + " channels"); print_line("PulseAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms"); } pa_buffer_attr attr; // set to appropriate buffer length (in bytes) from global settings - attr.tlength = buffer_size * sizeof(int16_t); + attr.tlength = pa_buffer_size * sizeof(int16_t); // set them to be automatically chosen attr.prebuf = (uint32_t)-1; attr.maxlength = (uint32_t)-1; attr.minreq = (uint32_t)-1; - int error_code; - pulse = pa_simple_new(NULL, // default server - "Godot", // application name - PA_STREAM_PLAYBACK, - NULL, // default device - "Sound", // stream description - &spec, - NULL, // use default channel map - &attr, // use buffering attributes from above - &error_code); - - if (pulse == NULL) { - fprintf(stderr, "PulseAudio ERR: %s\n", pa_strerror(error_code)); - ERR_FAIL_COND_V(pulse == NULL, ERR_CANT_OPEN); + pa_str = pa_stream_new(pa_ctx, "Sound", &spec, NULL); + ERR_FAIL_COND_V(pa_ctx == NULL, ERR_CANT_OPEN); + + const char *dev = device_name == "Default" ? NULL : device_name.utf8().get_data(); + pa_stream_flags flags = pa_stream_flags(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE); + int error_code = pa_stream_connect_playback(pa_str, dev, &attr, flags, NULL, NULL); + ERR_FAIL_COND_V(error_code < 0, ERR_CANT_OPEN); + + samples_in.resize(buffer_frames * channels); + samples_out.resize(pa_buffer_size); + + return OK; +} + +Error AudioDriverPulseAudio::init() { + + active = false; + thread_exited = false; + exit_thread = false; + + mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE); + + pa_ml = pa_mainloop_new(); + ERR_FAIL_COND_V(pa_ml == NULL, ERR_CANT_OPEN); + + pa_ctx = pa_context_new(pa_mainloop_get_api(pa_ml), "Godot"); + ERR_FAIL_COND_V(pa_ctx == NULL, ERR_CANT_OPEN); + + pa_ready = 0; + pa_context_set_state_callback(pa_ctx, pa_state_cb, (void *)this); + + int ret = pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL); + if (ret < 0) { + if (pa_ctx) { + pa_context_unref(pa_ctx); + pa_ctx = NULL; + } + + if (pa_ml) { + pa_mainloop_free(pa_ml); + pa_ml = NULL; + } + + return ERR_CANT_OPEN; } - samples_in.resize(buffer_size); - samples_out.resize(buffer_size); + while (pa_ready == 0) { + pa_mainloop_iterate(pa_ml, 1, NULL); + } - mutex = Mutex::create(); - thread = Thread::create(AudioDriverPulseAudio::thread_func, this); + if (pa_ready < 0) { + if (pa_ctx) { + pa_context_disconnect(pa_ctx); + pa_context_unref(pa_ctx); + pa_ctx = NULL; + } + + if (pa_ml) { + pa_mainloop_free(pa_ml); + pa_ml = NULL; + } + + return ERR_CANT_OPEN; + } + + Error err = init_device(); + if (err == OK) { + mutex = Mutex::create(); + thread = Thread::create(AudioDriverPulseAudio::thread_func, this); + } return OK; } @@ -221,9 +253,24 @@ Error AudioDriverPulseAudio::init() { float AudioDriverPulseAudio::get_latency() { if (latency == 0) { //only do this once since it's approximate anyway - int error_code; - pa_usec_t palat = pa_simple_get_latency(pulse, &error_code); - latency = double(palat) / 1000000.0; + lock(); + + pa_usec_t palat = 0; + if (pa_stream_get_state(pa_str) == PA_STREAM_READY) { + int negative = 0; + + if (pa_stream_get_latency(pa_str, &palat, &negative) >= 0) { + if (negative) { + palat = 0; + } + } + } + + if (palat > 0) { + latency = double(palat) / 1000000.0; + } + + unlock(); } return latency; @@ -235,7 +282,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { while (!ad->exit_thread) { if (!ad->active) { - for (unsigned int i = 0; i < ad->buffer_size; i++) { + for (unsigned int i = 0; i < ad->pa_buffer_size; i++) { ad->samples_out[i] = 0; } @@ -246,22 +293,77 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { ad->unlock(); - for (unsigned int i = 0; i < ad->buffer_size; i++) { - ad->samples_out[i] = ad->samples_in[i] >> 16; + if (ad->channels == ad->pa_channels) { + for (unsigned int i = 0; i < ad->pa_buffer_size; i++) { + ad->samples_out[i] = ad->samples_in[i] >> 16; + } + } else { + // Uneven amount of channels + unsigned int in_idx = 0; + unsigned int out_idx = 0; + + for (unsigned int i = 0; i < ad->buffer_frames; i++) { + for (unsigned int j = 0; j < ad->pa_channels - 1; j++) { + ad->samples_out[out_idx++] = ad->samples_in[in_idx++] >> 16; + } + uint32_t l = ad->samples_in[in_idx++]; + uint32_t r = ad->samples_in[in_idx++]; + ad->samples_out[out_idx++] = (l >> 1 + r >> 1) >> 16; + } } } - // pa_simple_write always consumes the entire buffer - int error_code; - int byte_size = ad->buffer_size * sizeof(int16_t); - if (pa_simple_write(ad->pulse, ad->samples_out.ptr(), byte_size, &error_code) < 0) { - // can't recover here - fprintf(stderr, "PulseAudio failed and can't recover: %s\n", pa_strerror(error_code)); - ad->active = false; - ad->exit_thread = true; - break; + int byte_size = ad->pa_buffer_size * sizeof(int16_t); + + ad->lock(); + + int ret; + do { + ret = pa_mainloop_iterate(ad->pa_ml, 0, NULL); + } while (ret > 0); + + if (pa_stream_get_state(ad->pa_str) == PA_STREAM_READY) { + const void *ptr = ad->samples_out.ptr(); + while (byte_size > 0) { + size_t bytes = pa_stream_writable_size(ad->pa_str); + if (bytes > 0) { + if (bytes > byte_size) { + bytes = byte_size; + } + + int ret = pa_stream_write(ad->pa_str, ptr, bytes, NULL, 0LL, PA_SEEK_RELATIVE); + if (ret >= 0) { + byte_size -= bytes; + ptr = (const char *)ptr + bytes; + } + } else { + pa_mainloop_iterate(ad->pa_ml, 1, NULL); + } + } + } + + // User selected a new device, finish the current one so we'll init the new device + if (ad->device_name != ad->new_device) { + ad->device_name = ad->new_device; + ad->finish_device(); + + Error err = ad->init_device(); + if (err != OK) { + ERR_PRINT("PulseAudio: init_device error"); + ad->device_name = "Default"; + ad->new_device = "Default"; + + err = ad->init_device(); + if (err != OK) { + ad->active = false; + ad->exit_thread = true; + break; + } + } } + + ad->unlock(); } ad->thread_exited = true; @@ -282,6 +384,61 @@ AudioDriver::SpeakerMode AudioDriverPulseAudio::get_speaker_mode() const { return get_speaker_mode_by_total_channels(channels); } +void AudioDriverPulseAudio::pa_sinklist_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata) { + AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata; + int ctr = 0; + + // If eol is set to a positive number, you're at the end of the list + if (eol > 0) { + return; + } + + ad->pa_devices.push_back(l->name); + ad->pa_status++; +} + +Array AudioDriverPulseAudio::get_device_list() { + + pa_devices.clear(); + pa_devices.push_back("Default"); + + if (pa_ctx == NULL) { + return pa_devices; + } + + lock(); + + // Get the device list + pa_status = 0; + pa_operation *pa_op = pa_context_get_sink_info_list(pa_ctx, pa_sinklist_cb, (void *)this); + if (pa_op) { + while (pa_status == 0) { + int ret = pa_mainloop_iterate(pa_ml, 1, NULL); + if (ret < 0) { + ERR_PRINT("pa_mainloop_iterate error"); + } + } + + pa_operation_unref(pa_op); + } else { + ERR_PRINT("pa_context_get_server_info error"); + } + + unlock(); + + return pa_devices; +} + +String AudioDriverPulseAudio::get_device() { + + return device_name; +} + +void AudioDriverPulseAudio::set_device(String device) { + + new_device = device; +} + void AudioDriverPulseAudio::lock() { if (!thread || !mutex) @@ -296,6 +453,15 @@ void AudioDriverPulseAudio::unlock() { mutex->unlock(); } +void AudioDriverPulseAudio::finish_device() { + + if (pa_str) { + pa_stream_disconnect(pa_str); + pa_stream_unref(pa_str); + pa_str = NULL; + } +} + void AudioDriverPulseAudio::finish() { if (!thread) @@ -304,9 +470,17 @@ void AudioDriverPulseAudio::finish() { exit_thread = true; Thread::wait_to_finish(thread); - if (pulse) { - pa_simple_free(pulse); - pulse = NULL; + finish_device(); + + if (pa_ctx) { + pa_context_disconnect(pa_ctx); + pa_context_unref(pa_ctx); + pa_ctx = NULL; + } + + if (pa_ml) { + pa_mainloop_free(pa_ml); + pa_ml = NULL; } memdelete(thread); @@ -320,25 +494,33 @@ void AudioDriverPulseAudio::finish() { AudioDriverPulseAudio::AudioDriverPulseAudio() { + pa_ml = NULL; + pa_ctx = NULL; + pa_str = NULL; + mutex = NULL; thread = NULL; - pulse = NULL; + + device_name = "Default"; + new_device = "Default"; + default_device = ""; samples_in.clear(); samples_out.clear(); mix_rate = 0; - buffer_size = 0; + buffer_frames = 0; + pa_buffer_size = 0; channels = 0; + pa_channels = 0; + pa_ready = 0; + pa_status = 0; active = false; thread_exited = false; exit_thread = false; latency = 0; - buffer_frames = 0; - buffer_size = 0; - channels = 0; } AudioDriverPulseAudio::~AudioDriverPulseAudio() { diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h index 3bd1146f53..934031e2a5 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.h +++ b/drivers/pulseaudio/audio_driver_pulseaudio.h @@ -37,22 +37,32 @@ #include "core/os/thread.h" #include "servers/audio_server.h" -#include <pulse/simple.h> +#include <pulse/pulseaudio.h> class AudioDriverPulseAudio : public AudioDriver { Thread *thread; Mutex *mutex; - pa_simple *pulse; + pa_mainloop *pa_ml; + pa_context *pa_ctx; + pa_stream *pa_str; + + String device_name; + String new_device; + String default_device; Vector<int32_t> samples_in; Vector<int16_t> samples_out; unsigned int mix_rate; unsigned int buffer_frames; - unsigned int buffer_size; + unsigned int pa_buffer_size; int channels; + int pa_channels; + int pa_ready; + int pa_status; + Array pa_devices; bool active; bool thread_exited; @@ -60,6 +70,16 @@ class AudioDriverPulseAudio : public AudioDriver { float latency; + static void pa_state_cb(pa_context *c, void *userdata); + static void pa_sink_info_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata); + static void pa_server_info_cb(pa_context *c, const pa_server_info *i, void *userdata); + static void pa_sinklist_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata); + + Error init_device(); + void finish_device(); + + void detect_channels(); + static void thread_func(void *p_udata); public: @@ -71,6 +91,9 @@ public: virtual void start(); virtual int get_mix_rate() const; virtual SpeakerMode get_speaker_mode() const; + virtual Array get_device_list(); + virtual String get_device(); + virtual void set_device(String device); virtual void lock(); virtual void unlock(); virtual void finish(); diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 3944431516..5a4be6df4f 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -244,7 +244,7 @@ static void _get_drives(List<String> *list) { // Parse only file:// links if (strncmp(string, "file://", 7) == 0) { // Strip any unwanted edges on the strings and push_back if it's not a duplicate - String fpath = String(string + 7).strip_edges(); + String fpath = String(string + 7).strip_edges().split_spaces()[0].percent_decode(); if (!list->find(fpath)) { list->push_back(fpath); } diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 5b093a5885..a7a3eef935 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -69,6 +69,7 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) { fclose(f); f = NULL; + path_src = p_path; path = fix_path(p_path); //printf("opening %ls, %i\n", path.c_str(), Memory::get_static_mem_usage()); @@ -152,6 +153,16 @@ bool FileAccessUnix::is_open() const { return (f != NULL); } +String FileAccessUnix::get_path() const { + + return path_src; +} + +String FileAccessUnix::get_path_absolute() const { + + return path; +} + void FileAccessUnix::seek(size_t p_position) { ERR_FAIL_COND(!f); diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index dbb1c9f3b5..88bb39fbd1 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -51,6 +51,7 @@ class FileAccessUnix : public FileAccess { mutable Error last_error; String save_path; String path; + String path_src; static FileAccess *create_libc(); @@ -61,6 +62,9 @@ public: virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open + virtual String get_path() const; /// returns the path for the current open file + virtual String get_path_absolute() const; /// returns the absolute path for the current open file + virtual void seek(size_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file virtual size_t get_position() const; ///< get position in the file diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index aa01f22673..31c8e4ade9 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -73,15 +73,6 @@ void OS_Unix::debug_break() { assert(false); }; -int OS_Unix::get_audio_driver_count() const { - - return 1; -} -const char *OS_Unix::get_audio_driver_name(int p_driver) const { - - return "dummy"; -} - int OS_Unix::unix_initialize_audio(int p_audio_driver) { return 0; @@ -98,10 +89,11 @@ void handle_sigchld(int sig) { void OS_Unix::initialize_core() { -#ifdef NO_PTHREADS +#ifdef NO_THREADS ThreadDummy::make_default(); SemaphoreDummy::make_default(); MutexDummy::make_default(); + RWLockDummy::make_default(); #else ThreadPosix::make_default(); SemaphorePosix::make_default(); diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index a7c9015330..db0fe1e00b 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -48,12 +48,6 @@ protected: // UNIX only handles the core functions. // inheriting platforms under unix (eg. X11) should handle the rest - //virtual int get_video_driver_count() const; - //virtual const char * get_video_driver_name(int p_driver) const; - - virtual int get_audio_driver_count() const; - virtual const char *get_audio_driver_name(int p_driver) const; - virtual void initialize_core(); virtual int unix_initialize_audio(int p_audio_driver); //virtual Error initialize(int p_video_driver,int p_audio_driver); diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp index f079ae2ae2..a73b40a6f2 100644 --- a/drivers/unix/thread_posix.cpp +++ b/drivers/unix/thread_posix.cpp @@ -31,7 +31,7 @@ #include "thread_posix.h" #include "script_language.h" -#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) +#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS) #ifdef PTHREAD_BSD_SET_NAME #include <pthread_np.h> diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h index 15c9265e6d..ea2de61bd5 100644 --- a/drivers/unix/thread_posix.h +++ b/drivers/unix/thread_posix.h @@ -35,7 +35,7 @@ @author Juan Linietsky <reduzio@gmail.com> */ -#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) +#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS) #include "os/thread.h" #include <pthread.h> diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 36acfb10d1..966b69a67e 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -35,6 +35,8 @@ #include "os/os.h" #include "project_settings.h" +#include <functiondiscoverykeys.h> + const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator); const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator); const IID IID_IAudioClient = __uuidof(IAudioClient); @@ -121,7 +123,61 @@ Error AudioDriverWASAPI::init_device(bool reinit) { HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&enumerator); ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); - hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &device); + if (device_name == "Default") { + hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &device); + } else { + IMMDeviceCollection *devices = NULL; + + hr = enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &devices); + ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); + + LPWSTR strId = NULL; + bool found = false; + + UINT count = 0; + hr = devices->GetCount(&count); + ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); + + for (ULONG i = 0; i < count && !found; i++) { + IMMDevice *device = NULL; + + hr = devices->Item(i, &device); + ERR_BREAK(hr != S_OK); + + IPropertyStore *props = NULL; + hr = device->OpenPropertyStore(STGM_READ, &props); + ERR_BREAK(hr != S_OK); + + PROPVARIANT propvar; + PropVariantInit(&propvar); + + hr = props->GetValue(PKEY_Device_FriendlyName, &propvar); + ERR_BREAK(hr != S_OK); + + if (device_name == String(propvar.pwszVal)) { + hr = device->GetId(&strId); + ERR_BREAK(hr != S_OK); + + found = true; + } + + PropVariantClear(&propvar); + props->Release(); + device->Release(); + } + + if (found) { + hr = enumerator->GetDevice(strId, &device); + } + + if (strId) { + CoTaskMemFree(strId); + } + + if (device == NULL) { + hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &device); + } + } if (reinit) { // In case we're trying to re-initialize the device prevent throwing this error on the console, // otherwise if there is currently no device available this will spam the console. @@ -151,7 +207,6 @@ Error AudioDriverWASAPI::init_device(bool reinit) { // Since we're using WASAPI Shared Mode we can't control any of these, we just tag along wasapi_channels = pwfex->nChannels; - mix_rate = pwfex->nSamplesPerSec; format_tag = pwfex->wFormatTag; bits_per_sample = pwfex->wBitsPerSample; @@ -187,7 +242,14 @@ Error AudioDriverWASAPI::init_device(bool reinit) { } } - hr = audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 0, 0, pwfex, NULL); + DWORD streamflags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK; + if (mix_rate != pwfex->nSamplesPerSec) { + streamflags |= AUDCLNT_STREAMFLAGS_RATEADJUST; + pwfex->nSamplesPerSec = mix_rate; + pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nChannels * (pwfex->wBitsPerSample / 8); + } + + hr = audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, streamflags, 0, 0, pwfex, NULL); ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); event = CreateEvent(NULL, FALSE, FALSE, NULL); @@ -223,10 +285,11 @@ Error AudioDriverWASAPI::finish_device() { if (audio_client) { if (active) { audio_client->Stop(); - audio_client->Release(); - audio_client = NULL; active = false; } + + audio_client->Release(); + audio_client = NULL; } if (render_client) { @@ -244,6 +307,8 @@ Error AudioDriverWASAPI::finish_device() { Error AudioDriverWASAPI::init() { + mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE); + Error err = init_device(); if (err != OK) { ERR_PRINT("WASAPI: init_device error"); @@ -285,6 +350,64 @@ AudioDriver::SpeakerMode AudioDriverWASAPI::get_speaker_mode() const { return get_speaker_mode_by_total_channels(channels); } +Array AudioDriverWASAPI::get_device_list() { + + Array list; + IMMDeviceCollection *devices = NULL; + IMMDeviceEnumerator *enumerator = NULL; + + list.push_back(String("Default")); + + CoInitialize(NULL); + + HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&enumerator); + ERR_FAIL_COND_V(hr != S_OK, Array()); + + hr = enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &devices); + ERR_FAIL_COND_V(hr != S_OK, Array()); + + UINT count = 0; + hr = devices->GetCount(&count); + ERR_FAIL_COND_V(hr != S_OK, Array()); + + for (ULONG i = 0; i < count; i++) { + IMMDevice *device = NULL; + + hr = devices->Item(i, &device); + ERR_BREAK(hr != S_OK); + + IPropertyStore *props = NULL; + hr = device->OpenPropertyStore(STGM_READ, &props); + ERR_BREAK(hr != S_OK); + + PROPVARIANT propvar; + PropVariantInit(&propvar); + + hr = props->GetValue(PKEY_Device_FriendlyName, &propvar); + ERR_BREAK(hr != S_OK); + + list.push_back(String(propvar.pwszVal)); + + PropVariantClear(&propvar); + props->Release(); + device->Release(); + } + + devices->Release(); + enumerator->Release(); + return list; +} + +String AudioDriverWASAPI::get_device() { + + return device_name; +} + +void AudioDriverWASAPI::set_device(String device) { + + new_device = device; +} + void AudioDriverWASAPI::write_sample(AudioDriverWASAPI *ad, BYTE *buffer, int i, int32_t sample) { if (ad->format_tag == WAVE_FORMAT_PCM) { switch (ad->bits_per_sample) { @@ -400,7 +523,8 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { } } - if (default_device_changed) { + // If we're using the Default device and it changed finish it so we'll re-init the device + if (ad->device_name == "Default" && default_device_changed) { Error err = ad->finish_device(); if (err != OK) { ERR_PRINT("WASAPI: finish_device error"); @@ -409,6 +533,15 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { default_device_changed = false; } + // User selected a new device, finish the current one so we'll init the new device + if (ad->device_name != ad->new_device) { + ad->device_name = ad->new_device; + Error err = ad->finish_device(); + if (err != OK) { + ERR_PRINT("WASAPI: finish_device error"); + } + } + if (!ad->audio_client) { Error err = ad->init_device(true); if (err == OK) { @@ -483,6 +616,9 @@ AudioDriverWASAPI::AudioDriverWASAPI() { thread_exited = false; exit_thread = false; active = false; + + device_name = "Default"; + new_device = "Default"; } #endif diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index 2b19f0cca1..c97f4c288c 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/drivers/wasapi/audio_driver_wasapi.h @@ -49,6 +49,9 @@ class AudioDriverWASAPI : public AudioDriver { Mutex *mutex; Thread *thread; + String device_name; + String new_device; + WORD format_tag; WORD bits_per_sample; @@ -80,6 +83,9 @@ public: virtual void start(); virtual int get_mix_rate() const; virtual SpeakerMode get_speaker_mode() const; + virtual Array get_device_list(); + virtual String get_device(); + virtual void set_device(String device); virtual void lock(); virtual void unlock(); virtual void finish(); diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index 2e64b55430..cf4d82fb07 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -261,13 +261,30 @@ Error DirAccessWindows::rename(String p_path, String p_new_path) { p_new_path = fix_path(p_new_path); - if (file_exists(p_new_path)) { - if (remove(p_new_path) != OK) { + // If we're only changing file name case we need to do a little juggling + if (p_path.to_lower() == p_new_path.to_lower()) { + WCHAR tmpfile[MAX_PATH]; + + if (!GetTempFileNameW(fix_path(get_current_dir()).c_str(), NULL, 0, tmpfile)) { return FAILED; - }; - }; + } + + if (!::ReplaceFileW(tmpfile, p_path.c_str(), NULL, 0, NULL, NULL)) { + DeleteFileW(tmpfile); + return FAILED; + } - return ::_wrename(p_path.c_str(), p_new_path.c_str()) == 0 ? OK : FAILED; + return ::_wrename(tmpfile, p_new_path.c_str()) == 0 ? OK : FAILED; + + } else { + if (file_exists(p_new_path)) { + if (remove(p_new_path) != OK) { + return FAILED; + } + } + + return ::_wrename(p_path.c_str(), p_new_path.c_str()) == 0 ? OK : FAILED; + } } Error DirAccessWindows::remove(String p_path) { diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index 072790876f..23c8ea2ec7 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -57,7 +57,8 @@ void FileAccessWindows::check_errors() const { Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) { - String filename = fix_path(p_path); + path_src = p_path; + path = fix_path(p_path); if (f) close(); @@ -78,19 +79,19 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) { backend supports utf8 encoding */ struct _stat st; - if (_wstat(filename.c_str(), &st) == 0) { + if (_wstat(path.c_str(), &st) == 0) { if (!S_ISREG(st.st_mode)) return ERR_FILE_CANT_OPEN; }; if (is_backup_save_enabled() && p_mode_flags & WRITE && !(p_mode_flags & READ)) { - save_path = filename; - filename = filename + ".tmp"; + save_path = path; + path = path + ".tmp"; //print_line("saving instead to "+path); } - f = _wfopen(filename.c_str(), mode_string); + f = _wfopen(path.c_str(), mode_string); if (f == NULL) { last_error = ERR_FILE_CANT_OPEN; @@ -138,22 +139,36 @@ void FileAccessWindows::close() { //atomic replace for existing file rename_error = !ReplaceFileW(save_path.c_str(), (save_path + ".tmp").c_str(), NULL, 2 | 4, NULL, NULL); } - if (rename_error && close_fail_notify) { - close_fail_notify(save_path); - } if (rename_error) { attempts--; OS::get_singleton()->delay_usec(1000000); //wait 100msec and try again } } - save_path = ""; if (rename_error) { + if (close_fail_notify) { + close_fail_notify(save_path); + } + ERR_EXPLAIN("Safe save failed. This may be a permissions problem, but also may happen because you are running a paranoid antivirus. If this is the case, please switch to Windows Defender or disable the 'safe save' option in editor settings. This makes it work, but increases the risk of file corruption in a crash."); } + + save_path = ""; + ERR_FAIL_COND(rename_error); } } + +String FileAccessWindows::get_path() const { + + return path_src; +} + +String FileAccessWindows::get_path_absolute() const { + + return path; +} + bool FileAccessWindows::is_open() const { return (f != NULL); diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h index 26bd08b7af..0462c1e942 100644 --- a/drivers/windows/file_access_windows.h +++ b/drivers/windows/file_access_windows.h @@ -46,6 +46,8 @@ class FileAccessWindows : public FileAccess { int flags; void check_errors() const; mutable Error last_error; + String path; + String path_src; String save_path; public: @@ -53,6 +55,9 @@ public: virtual void close(); ///< close a file virtual bool is_open() const; ///< true when file is open + virtual String get_path() const; /// returns the path for the current open file + virtual String get_path_absolute() const; /// returns the absolute path for the current open file + virtual void seek(size_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file virtual size_t get_position() const; ///< get position in the file diff --git a/editor/SCsub b/editor/SCsub index 8f87e12cb9..4ca6b9e3fd 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -4,6 +4,7 @@ Import('env') env.editor_sources = [] import os +import os.path from compat import encode_utf8, byte_to_str, open_utf8, escape_string @@ -29,6 +30,9 @@ def make_certs_header(target, source, env): g.write("};\n") g.write("#endif") + g.close() + f.close() + def make_doc_header(target, source, env): @@ -41,8 +45,8 @@ def make_doc_header(target, source, env): src = s.srcnode().abspath if not src.endswith(".xml"): continue - f = open_utf8(src, "r") - content = f.read() + with open_utf8(src, "r") as f: + content = f.read() buf += content buf = encode_utf8(docbegin + buf + docend) @@ -62,6 +66,8 @@ def make_doc_header(target, source, env): g.write("#endif") + g.close() + def make_fonts_header(target, source, env): @@ -76,9 +82,8 @@ def make_fonts_header(target, source, env): # saving uncompressed, since freetype will reference from memory pointer xl_names = [] for i in range(len(source)): - f = open(source[i].srcnode().abspath, "rb") - buf = f.read() - import os.path + with open(source[i].srcnode().abspath, "rb")as f: + buf = f.read() name = os.path.splitext(os.path.basename(source[i].srcnode().abspath))[0] @@ -91,6 +96,8 @@ def make_fonts_header(target, source, env): g.write("#endif") + g.close() + def make_translations_header(target, source, env): @@ -110,8 +117,8 @@ def make_translations_header(target, source, env): xl_names = [] for i in range(len(sorted_paths)): - f = open(sorted_paths[i], "rb") - buf = f.read() + with open(sorted_paths[i], "rb") as f: + buf = f.read() decomp_size = len(buf) buf = zlib.compress(buf) name = os.path.splitext(os.path.basename(sorted_paths[i]))[0] @@ -138,6 +145,9 @@ def make_translations_header(target, source, env): g.write("#endif") + g.close() + + def make_authors_header(target, source, env): sections = ["Project Founders", "Lead Developer", "Project Manager", "Developers"] @@ -180,6 +190,9 @@ def make_authors_header(target, source, env): g.write("#endif\n") + g.close() + f.close() + def make_donors_header(target, source, env): sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors", "Gold donors", "Silver donors", "Bronze donors"] @@ -222,6 +235,10 @@ def make_donors_header(target, source, env): g.write("#endif\n") + g.close() + f.close() + + def make_license_header(target, source, env): src_copyright = source[0].srcnode().abspath @@ -387,17 +404,23 @@ def make_license_header(target, source, env): g.write("#endif\n") + g.close() + fc.close() + f.close() + def _make_doc_data_class_path(to_path): - g = open_utf8(os.path.join(to_path,"doc_data_class_path.gen.h"), "w") - g.write("static const int _doc_data_class_path_count = " + str(len(env.doc_class_path)) + ";\n") - g.write("struct _DocDataClassPath { const char* name; const char* path; };\n") + g = open_utf8(os.path.join(to_path,"doc_data_class_path.gen.h"), "w") + g.write("static const int _doc_data_class_path_count = " + str(len(env.doc_class_path)) + ";\n") + g.write("struct _DocDataClassPath { const char* name; const char* path; };\n") + + g.write("static const _DocDataClassPath _doc_data_class_paths[" + str(len(env.doc_class_path) + 1) + "] = {\n"); + for c in sorted(env.doc_class_path): + g.write("\t{\"" + c + "\", \"" + env.doc_class_path[c] + "\"},\n") + g.write("\t{NULL, NULL}\n") + g.write("};\n") - g.write("static const _DocDataClassPath _doc_data_class_paths[" + str(len(env.doc_class_path) + 1) + "] = {\n"); - for c in sorted(env.doc_class_path): - g.write("\t{\"" + c + "\", \"" + env.doc_class_path[c] + "\"},\n") - g.write("\t{NULL, NULL}\n") - g.write("};\n") + g.close() if env['tools']: @@ -409,10 +432,9 @@ if env['tools']: reg_exporters += '\tregister_' + e + '_exporter();\n' reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n' reg_exporters += '}\n' - f = open_utf8("register_exporters.gen.cpp", "w") - f.write(reg_exporters_inc) - f.write(reg_exporters) - f.close() + with open_utf8("register_exporters.gen.cpp", "w") as f: + f.write(reg_exporters_inc) + f.write(reg_exporters) # API documentation docs = [] @@ -466,6 +488,7 @@ if env['tools']: env.add_source_files(env.editor_sources, "*.cpp") + env.add_source_files(env.editor_sources, ["#thirdparty/misc/clipper.cpp"]) SConscript('collada/SCsub') SConscript('doc/SCsub') diff --git a/editor/animation_editor.cpp b/editor/animation_editor.cpp index c064f9cbdf..439ec37e71 100644 --- a/editor/animation_editor.cpp +++ b/editor/animation_editor.cpp @@ -1149,15 +1149,13 @@ void AnimationKeyEditor::_track_editor_draw() { get_icon("KeyCall", "EditorIcons") }; + Ref<Texture> valid_icon = get_icon("KeyValid", "EditorIcons"); Ref<Texture> invalid_icon = get_icon("KeyInvalid", "EditorIcons"); - Ref<Texture> invalid_icon_hover = get_icon("KeyInvalidHover", "EditorIcons"); + const Color modulate_selected = Color(0x84 / 255.0, 0xc2 / 255.0, 0xff / 255.0); Ref<Texture> hsize_icon = get_icon("Hsize", "EditorIcons"); - Ref<Texture> type_hover = get_icon("KeyHover", "EditorIcons"); - Ref<Texture> type_selected = get_icon("KeySelected", "EditorIcons"); - - int right_separator_ofs = down_icon->get_width() * 3 + add_key_icon->get_width() + interp_icon[0]->get_width() + wrap_icon[0]->get_width() + cont_icon[0]->get_width() + hsep * 9; + int right_separator_ofs = right_data_size_cache; int h = font->get_height() + sep; @@ -1268,8 +1266,21 @@ void AnimationKeyEditor::_track_editor_draw() { int decimals = 2; bool step_found = false; + const int period_width = font->get_char_size('.').width; + int max_digit_width = font->get_char_size('0').width; + for (int i = 1; i <= 9; i++) { + const int digit_width = font->get_char_size('0' + i).width; + max_digit_width = MAX(digit_width, max_digit_width); + } + const int max_sc = int(Math::ceil(zoomw / scale)); + const int max_sc_width = String::num(max_sc).length() * max_digit_width; + while (!step_found) { + min = max_sc_width; + if (decimals > 0) + min += period_width + max_digit_width * decimals; + static const int _multp[3] = { 1, 2, 5 }; for (int i = 0; i < 3; i++) { @@ -1464,6 +1475,10 @@ void AnimationKeyEditor::_track_editor_draw() { float x = key_hofs + name_limit + (time - keys_from) * zoom_scale; Ref<Texture> tex = type_icon[tt]; + Color modulate = Color(1, 1, 1); + + bool is_hover = false; + bool is_selected = false; SelectedKey sk; sk.key = i; @@ -1472,13 +1487,33 @@ void AnimationKeyEditor::_track_editor_draw() { if (click.click == ClickOver::CLICK_MOVE_KEYS) continue; - tex = type_selected; + is_selected = true; } if (mouse_over.over == MouseOver::OVER_KEY && mouse_over.track == idx && mouse_over.over_key == i) - tex = type_hover; + is_hover = true; Variant value = animation->track_get_key_value(idx, i); + + if (prop_exists && !Variant::can_convert(value.get_type(), valid_type)) { + + tex = invalid_icon; + if (is_hover) + modulate = Color(1.5, 1.5, 1.5); + else + modulate = Color(1, 1, 1); + } else if (is_selected) { + + tex = valid_icon; + modulate = modulate_selected; + if (is_hover) + modulate = modulate.lightened(0.2); + } else if (is_hover) { + + tex = valid_icon; + modulate = Color(1, 1, 1); + } + if (first && i > 0 && value == animation->track_get_key_value(idx, i - 1)) { te->draw_line(ofs + Vector2(name_limit, y + h / 2), ofs + Point2(x, y + h / 2), color); @@ -1491,19 +1526,7 @@ void AnimationKeyEditor::_track_editor_draw() { te->draw_line(ofs + Point2(x_n, y + h / 2), ofs + Point2(x, y + h / 2), color); } - if (prop_exists && !Variant::can_convert(value.get_type(), valid_type)) { - te->draw_texture(invalid_icon, ofs + Point2(x, y + key_vofs).floor()); - } - - if (prop_exists && !Variant::can_convert(value.get_type(), valid_type)) { - if (tex == type_hover) - te->draw_texture(invalid_icon_hover, ofs + Point2(x, y + key_vofs).floor()); - else - te->draw_texture(invalid_icon, ofs + Point2(x, y + key_vofs).floor()); - } else { - - te->draw_texture(tex, ofs + Point2(x, y + key_vofs).floor()); - } + te->draw_texture(tex, ofs + Point2(x, y + key_vofs).floor(), modulate); first = false; } @@ -1539,8 +1562,8 @@ void AnimationKeyEditor::_track_editor_draw() { continue; int y = h + i * h + sep; - float key_vofs = Math::floor((float)(h - type_selected->get_height()) / 2); - float key_hofs = -Math::floor((float)type_selected->get_height() / 2); + float key_vofs = Math::floor((float)(h - valid_icon->get_height()) / 2); + float key_hofs = -Math::floor((float)valid_icon->get_height() / 2); float time = animation->track_get_key_time(idx, E->key().key); float diff = time - from_t; @@ -1554,7 +1577,7 @@ void AnimationKeyEditor::_track_editor_draw() { x += name_limit; - te->draw_texture(type_selected, ofs + Point2(x + key_hofs, y + key_vofs).floor()); + te->draw_texture(valid_icon, ofs + Point2(x + key_hofs, y + key_vofs).floor(), modulate_selected); } } break; default: {}; @@ -1830,7 +1853,7 @@ void AnimationKeyEditor::_track_editor_gui_input(const Ref<InputEvent> &p_input) get_icon("KeyXform", "EditorIcons"), get_icon("KeyCall", "EditorIcons") }; - int right_separator_ofs = down_icon->get_width() * 3 + add_key_icon->get_width() + interp_icon[0]->get_width() + wrap_icon[0]->get_width() + cont_icon[0]->get_width() + hsep * 9; + int right_separator_ofs = right_data_size_cache; int h = font->get_height() + sep; @@ -2930,8 +2953,8 @@ void AnimationKeyEditor::_track_editor_gui_input(const Ref<InputEvent> &p_input) Ref<InputEventPanGesture> pan_gesture = p_input; if (pan_gesture.is_valid()) { - h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * pan_gesture->get_delta().x / 8); - v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * pan_gesture->get_delta().y / 8); + h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * pan_gesture->get_delta().x / 8); + v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * pan_gesture->get_delta().y / 8); } } @@ -3042,7 +3065,7 @@ void AnimationKeyEditor::_notification(int p_what) { get_icon("InterpWrapClamp", "EditorIcons"), get_icon("InterpWrapLoop", "EditorIcons"), }; - right_data_size_cache = down_icon->get_width() * 3 + add_key_icon->get_width() + interp_icon[0]->get_width() + cont_icon[0]->get_width() + wrap_icon[0]->get_width() + hsep * 8; + right_data_size_cache = down_icon->get_width() * 3 + add_key_icon->get_width() + interp_icon[0]->get_width() + cont_icon[0]->get_width() + wrap_icon[0]->get_width() + hsep * 9; } } break; } @@ -3998,6 +4021,7 @@ AnimationKeyEditor::AnimationKeyEditor() { //key_edit->ke_dialog=key_edit_dialog; type_menu = memnew(PopupMenu); + type_menu->set_pass_on_modal_close_click(false); add_child(type_menu); for (int i = 0; i < Variant::VARIANT_MAX; i++) type_menu->add_item(Variant::get_type_name(Variant::Type(i)), i); @@ -4038,6 +4062,7 @@ AnimationKeyEditor::AnimationKeyEditor() { add_child(track_name); track_name->connect("text_entered", this, "_track_name_changed"); track_menu = memnew(PopupMenu); + track_menu->set_pass_on_modal_close_click(false); add_child(track_menu); track_menu->connect("id_pressed", this, "_track_menu_selected"); diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 9ae9ab1501..4c7f2f53cc 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -212,35 +212,39 @@ void FindReplaceBar::_replace_all() { text_edit->begin_complex_operation(); - while (search_next()) { - - // replace area - Point2i match_from(result_line, result_col); - Point2i match_to(result_line, result_col + search_text_len); - - if (match_from < prev_match) - break; // done + if (search_current()) { + do { + // replace area + Point2i match_from(result_line, result_col); + Point2i match_to(result_line, result_col + search_text_len); + + if (match_from < prev_match) { + break; // done + } - prev_match = Point2i(result_line, result_col + replace_text.length()); + prev_match = Point2i(result_line, result_col + replace_text.length()); - text_edit->unfold_line(result_line); - text_edit->select(result_line, result_col, result_line, match_to.y); + text_edit->unfold_line(result_line); + text_edit->select(result_line, result_col, result_line, match_to.y); - if (selection_enabled && is_selection_only()) { + if (selection_enabled && is_selection_only()) { + if (match_from < selection_begin || match_to > selection_end) { + continue; + } - if (match_from < selection_begin || match_to > selection_end) - continue; + // replace but adjust selection bounds + text_edit->insert_text_at_cursor(replace_text); + if (match_to.x == selection_end.x) { + selection_end.y += replace_text.length() - search_text_len; + } - // replace but adjust selection bounds - text_edit->insert_text_at_cursor(replace_text); - if (match_to.x == selection_end.x) - selection_end.y += replace_text.length() - search_text_len; - } else { - // just replace - text_edit->insert_text_at_cursor(replace_text); - } + } else { + // just replace + text_edit->insert_text_at_cursor(replace_text); + } - rc++; + rc++; + } while (search_next()); } text_edit->end_complex_operation(); diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index fdc58e6292..13ef6e9e0e 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -476,6 +476,8 @@ void CreateDialog::_item_selected() { return; help_bit->set_text(EditorHelp::get_doc_data()->class_list[name].brief_description); + + get_ok()->set_disabled(false); } void CreateDialog::_favorite_toggled() { diff --git a/editor/dictionary_property_edit.cpp b/editor/dictionary_property_edit.cpp index 4c0ad59385..a87edfd00d 100644 --- a/editor/dictionary_property_edit.cpp +++ b/editor/dictionary_property_edit.cpp @@ -41,7 +41,7 @@ void DictionaryPropertyEdit::_notif_changev(const String &p_v) { void DictionaryPropertyEdit::_set_key(const Variant &p_old_key, const Variant &p_new_key) { - // TODO: Set key of a dictionary is not allowd yet + // TODO: Set key of a dictionary is not allowed yet return; } diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp index 3a418e5f33..3434aa33f9 100644 --- a/editor/doc/doc_data.cpp +++ b/editor/doc/doc_data.cpp @@ -974,7 +974,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri if (c.category == "") category = "Core"; header += " category=\"" + category + "\""; - header += String(" version=\"") + itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + VERSION_STATUS + "\""; + header += String(" version=\"") + VERSION_NUMBER + "\""; header += ">"; _write_string(f, 0, header); _write_string(f, 1, "<brief_description>"); diff --git a/editor/doc/doc_dump.cpp b/editor/doc/doc_dump.cpp index 905732a43f..adbe23dcd5 100644 --- a/editor/doc/doc_dump.cpp +++ b/editor/doc/doc_dump.cpp @@ -83,7 +83,7 @@ void DocDump::dump(const String &p_file) { FileAccess *f = FileAccess::open(p_file, FileAccess::WRITE); _write_string(f, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); - _write_string(f, 0, String("<doc version=\"") + itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + VERSION_STATUS + "\" name=\"Engine Types\">"); + _write_string(f, 0, String("<doc version=\"") + VERSION_NUMBER + "\" name=\"Engine Types\">"); while (class_list.size()) { diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 9ab539da07..360ed620f6 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -44,9 +44,11 @@ void EditorAbout::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - Ref<Font> font = EditorNode::get_singleton()->get_gui_base()->get_font("source", "EditorFonts"); + Control *base = EditorNode::get_singleton()->get_gui_base(); + Ref<Font> font = base->get_font("source", "EditorFonts"); _tpl_text->add_font_override("normal_font", font); _license_text->add_font_override("normal_font", font); + _logo->set_texture(base->get_icon("Logo", "EditorIcons")); } break; } } diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 9d0de930f2..ac4402d50b 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -121,6 +121,26 @@ void EditorAudioBus::_notification(int p_what) { set_process(is_visible_in_tree()); } + + if (p_what == NOTIFICATION_THEME_CHANGED) { + + for (int i = 0; i < cc; i++) { + channel[i].vu_l->set_under_texture(get_icon("BusVuEmpty", "EditorIcons")); + channel[i].vu_l->set_progress_texture(get_icon("BusVuFull", "EditorIcons")); + channel[i].vu_r->set_under_texture(get_icon("BusVuEmpty", "EditorIcons")); + channel[i].vu_r->set_progress_texture(get_icon("BusVuFull", "EditorIcons")); + channel[i].prev_active = true; + } + scale->set_texture(get_icon("BusVuDb", "EditorIcons")); + + disabled_vu = get_icon("BusVuFrozen", "EditorIcons"); + + solo->set_icon(get_icon("AudioBusSolo", "EditorIcons")); + mute->set_icon(get_icon("AudioBusMute", "EditorIcons")); + bypass->set_icon(get_icon("AudioBusBypass", "EditorIcons")); + + bus_options->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); + } } void EditorAudioBus::update_send() { @@ -707,6 +727,9 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { channel[i].vu_r->set_min(-80); channel[i].vu_r->set_max(24); channel[i].vu_r->set_step(0.1); + + channel[i].peak_l = 0.0f; + channel[i].peak_r = 0.0f; } scale = memnew(TextureRect); @@ -716,6 +739,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { effects->set_hide_root(true); effects->set_custom_minimum_size(Size2(0, 100) * EDSCALE); effects->set_hide_folding(true); + effects->set_v_size_flags(SIZE_EXPAND_FILL); vb->add_child(effects); effects->connect("item_edited", this, "_effect_edited"); effects->connect("cell_selected", this, "_effect_selected"); @@ -1148,6 +1172,7 @@ EditorAudioBuses::EditorAudioBuses() { bus_scroll->set_enable_v_scroll(false); add_child(bus_scroll); bus_hb = memnew(HBoxContainer); + bus_hb->set_v_size_flags(SIZE_EXPAND_FILL); bus_scroll->add_child(bus_hb); save_timer = memnew(Timer); diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 0e9b7b74fd..a2f5c1aa1a 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -643,10 +643,10 @@ EditorAutoloadSettings::EditorAutoloadSettings() { tree->set_column_title(2, TTR("Singleton")); tree->set_column_expand(2, false); - tree->set_column_min_width(2, 80); + tree->set_column_min_width(2, 80 * EDSCALE); tree->set_column_expand(3, false); - tree->set_column_min_width(3, 120); + tree->set_column_min_width(3, 120 * EDSCALE); tree->connect("cell_selected", this, "_autoload_selected"); tree->connect("item_edited", this, "_autoload_edited"); diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index c9ac62a74d..7456cc902a 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -274,8 +274,6 @@ void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags) } Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { - if (p_path.ends_with(".so") || p_path.ends_with(".dylib") || p_path.ends_with(".dll")) - return OK; PackData *pd = (PackData *)p_userdata; @@ -337,7 +335,7 @@ Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_pat String EditorExportPlatform::find_export_template(String template_file_name, String *err) const { - String current_version = itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + VERSION_STATUS + VERSION_MODULE_CONFIG; + String current_version = VERSION_FULL_CONFIG; String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(current_version).plus_file(template_file_name); if (FileAccess::exists(template_path)) { @@ -1354,27 +1352,24 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); Error err = da->copy(template_path, p_path, get_chmod_flags()); - memdelete(da); - - if (err != OK) { - return err; - } - - String pck_path = p_path.get_basename() + ".pck"; + if (err == OK) { + String pck_path = p_path.get_basename() + ".pck"; - Vector<SharedObject> so_files; + Vector<SharedObject> so_files; - err = save_pack(p_preset, pck_path, &so_files); + err = save_pack(p_preset, pck_path, &so_files); - if (err != OK || so_files.empty()) - return err; - //if shared object files, copy them - da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - for (int i = 0; i < so_files.size(); i++) { - da->copy(so_files[i].path, p_path.get_base_dir().plus_file(so_files[i].path.get_file())); + if (err == OK && !so_files.empty()) { + //if shared object files, copy them + da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + for (int i = 0; i < so_files.size() && err == OK; i++) { + err = da->copy(so_files[i].path, p_path.get_base_dir().plus_file(so_files[i].path.get_file())); + } + } } + memdelete(da); - return OK; + return err; } void EditorExportPlatformPC::set_extension(const String &p_extension, const String &p_feature_key) { diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 22b33cc98f..c52f25e66b 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -551,7 +551,7 @@ void EditorFileDialog::_item_list_item_rmb_selected(int p_item, const Vector2 &p } if (single_item_selected) { - item_menu->add_icon_item(get_icon("CopyNodePath", "EditorIcons"), TTR("Copy Path"), ITEM_MENU_COPY_PATH); + item_menu->add_icon_item(get_icon("ActionCopy", "EditorIcons"), TTR("Copy Path"), ITEM_MENU_COPY_PATH); } if (allow_delete) { item_menu->add_icon_item(get_icon("Remove", "EditorIcons"), TTR("Delete"), ITEM_MENU_DELETE, KEY_DELETE); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index dca32d7492..d8ae1da72e 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -275,9 +275,13 @@ void EditorFileSystem::_scan_filesystem() { memdelete(d); f = FileAccess::open(fscache, FileAccess::WRITE); - _save_filesystem_cache(new_filesystem, f); - f->close(); - memdelete(f); + if (f == NULL) { + ERR_PRINTS("Error writing fscache: " + fscache); + } else { + _save_filesystem_cache(new_filesystem, f); + f->close(); + memdelete(f); + } scanning = false; } @@ -286,9 +290,13 @@ void EditorFileSystem::_save_filesystem_cache() { String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache3"); FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE); - _save_filesystem_cache(filesystem, f); - f->close(); - memdelete(f); + if (f == NULL) { + ERR_PRINTS("Error writing fscache: " + fscache); + } else { + _save_filesystem_cache(filesystem, f); + f->close(); + memdelete(f); + } } void EditorFileSystem::_thread_func(void *_userdata) { @@ -321,10 +329,10 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo List<String> to_check; - String source_file; - String source_md5; + String source_file = ""; + String source_md5 = ""; Vector<String> dest_files; - String dest_md5; + String dest_md5 = ""; while (true) { @@ -334,7 +342,6 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true); if (err == ERR_FILE_EOF) { - memdelete(f); break; } else if (err != OK) { ERR_PRINTS("ResourceFormatImporter::load - " + p_path + ".import:" + itos(lines) + " error: " + error_text); @@ -351,12 +358,8 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo to_check.push_back(fa[i]); } } else if (!p_only_imported_files) { - if (assign == "source_md5") { - source_md5 = value; - } else if (assign == "source_file") { + if (assign == "source_file") { source_file = value; - } else if (assign == "dest_md5") { - dest_md5 = value; } else if (assign == "dest_files") { dest_files = value; } @@ -369,6 +372,42 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo memdelete(f); + // Read the md5's from a separate file (so the import parameters aren't dependant on the file version + String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_path); + FileAccess *md5s = FileAccess::open(base_path + ".md5", FileAccess::READ, &err); + if (!md5s) { // No md5's stored for this resource + return true; + } + + VariantParser::StreamFile md5_stream; + md5_stream.f = md5s; + + while (true) { + assign = Variant(); + next_tag.fields.clear(); + next_tag.name = String(); + + err = VariantParser::parse_tag_assign_eof(&md5_stream, lines, error_text, next_tag, assign, value, NULL, true); + + if (err == ERR_FILE_EOF) { + break; + } else if (err != OK) { + ERR_PRINTS("ResourceFormatImporter::load - " + p_path + ".import.md5:" + itos(lines) + " error: " + error_text); + memdelete(md5s); + return false; // parse error + } + if (assign != String()) { + if (!p_only_imported_files) { + if (assign == "source_md5") { + source_md5 = value; + } else if (assign == "dest_md5") { + dest_md5 = value; + } + } + } + } + memdelete(md5s); + //imported files are gone, reimport for (List<String>::Element *E = to_check.front(); E; E = E->next()) { if (!FileAccess::exists(E->get())) { @@ -1316,6 +1355,9 @@ void EditorFileSystem::update_file(const String &p_file) { fs->files[cpos]->deps = _get_dependencies(p_file); fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file); + // Update preview + EditorResourcePreview::get_singleton()->check_for_invalidation(p_file); + call_deferred("emit_signal", "filesystem_changed"); //update later } @@ -1456,15 +1498,13 @@ void EditorFileSystem::_reimport_file(const String &p_file) { } f->store_line("source_file=" + Variant(p_file).get_construct_string()); - f->store_line("source_md5=\"" + FileAccess::get_md5(p_file) + "\"\n"); if (dest_paths.size()) { Array dp; for (int i = 0; i < dest_paths.size(); i++) { dp.push_back(dest_paths[i]); } - f->store_line("dest_files=" + Variant(dp).get_construct_string()); - f->store_line("dest_md5=\"" + FileAccess::get_multiple_md5(dest_paths) + "\"\n"); + f->store_line("dest_files=" + Variant(dp).get_construct_string() + "\n"); } f->store_line("[params]"); @@ -1483,6 +1523,16 @@ void EditorFileSystem::_reimport_file(const String &p_file) { f->close(); memdelete(f); + // Store the md5's of the various files. These are stored separately so that the .import files can be version controlled. + FileAccess *md5s = FileAccess::open(base_path + ".md5", FileAccess::WRITE); + ERR_FAIL_COND(!md5s); + md5s->store_line("source_md5=\"" + FileAccess::get_md5(p_file) + "\""); + if (dest_paths.size()) { + md5s->store_line("dest_md5=\"" + FileAccess::get_multiple_md5(dest_paths) + "\"\n"); + } + md5s->close(); + memdelete(md5s); + //update modified times, to avoid reimport fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file); fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file + ".import"); diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index a58257962a..2ec3cdb08f 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -103,9 +103,11 @@ void editor_register_fonts(Ref<Theme> p_theme) { /* Custom font */ String custom_font = EditorSettings::get_singleton()->get("interface/editor/main_font"); + DynamicFontData::Hinting font_hinting = (DynamicFontData::Hinting)(int)EditorSettings::get_singleton()->get("interface/editor/main_font_hinting"); Ref<DynamicFontData> CustomFont; if (custom_font.length() > 0) { CustomFont.instance(); + CustomFont->set_hinting(font_hinting); CustomFont->set_font_path(custom_font); CustomFont->set_force_autohinter(true); //just looks better..i think? } @@ -113,9 +115,11 @@ void editor_register_fonts(Ref<Theme> p_theme) { /* Custom source code font */ String custom_font_source = EditorSettings::get_singleton()->get("interface/editor/code_font"); + DynamicFontData::Hinting font_source_hinting = (DynamicFontData::Hinting)(int)EditorSettings::get_singleton()->get("interface/editor/code_font_hinting"); Ref<DynamicFontData> CustomFontSource; if (custom_font_source.length() > 0) { CustomFontSource.instance(); + CustomFontSource->set_hinting(font_source_hinting); CustomFontSource->set_font_path(custom_font_source); } @@ -123,38 +127,45 @@ void editor_register_fonts(Ref<Theme> p_theme) { Ref<DynamicFontData> DefaultFont; DefaultFont.instance(); + DefaultFont->set_hinting(font_hinting); DefaultFont->set_font_ptr(_font_NotoSansUI_Regular, _font_NotoSansUI_Regular_size); DefaultFont->set_force_autohinter(true); //just looks better..i think? Ref<DynamicFontData> FontFallback; FontFallback.instance(); + FontFallback->set_hinting(font_hinting); FontFallback->set_font_ptr(_font_DroidSansFallback, _font_DroidSansFallback_size); FontFallback->set_force_autohinter(true); //just looks better..i think? Ref<DynamicFontData> FontJapanese; FontJapanese.instance(); + FontJapanese->set_hinting(font_hinting); FontJapanese->set_font_ptr(_font_DroidSansJapanese, _font_DroidSansJapanese_size); FontJapanese->set_force_autohinter(true); //just looks better..i think? Ref<DynamicFontData> FontArabic; FontArabic.instance(); + FontArabic->set_hinting(font_hinting); FontArabic->set_font_ptr(_font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size); FontArabic->set_force_autohinter(true); //just looks better..i think? Ref<DynamicFontData> FontHebrew; FontHebrew.instance(); + FontHebrew->set_hinting(font_hinting); FontHebrew->set_font_ptr(_font_NotoSansHebrew_Regular, _font_NotoSansHebrew_Regular_size); FontHebrew->set_force_autohinter(true); //just looks better..i think? Ref<DynamicFontData> FontThai; FontThai.instance(); + FontThai->set_hinting(font_hinting); FontThai->set_font_ptr(_font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size); FontThai->set_force_autohinter(true); //just looks better..i think? - /* Source Code Pro */ + /* Hack */ Ref<DynamicFontData> dfmono; dfmono.instance(); + dfmono->set_hinting(font_source_hinting); dfmono->set_font_ptr(_font_Hack_Regular, _font_Hack_Regular_size); //dfd->set_force_autohinter(true); //just looks better..i think? diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 7f76cf1af2..f3be02a8c7 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -1172,7 +1172,12 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) { class_desc->push_indent(1); Vector<DocData::ConstantDoc> enum_list = E->get(); + Map<String, int> enumValuesContainer; + int enumStartingLine = enum_line[E->key()]; + for (int i = 0; i < enum_list.size(); i++) { + if (cd.name == "@GlobalScope") + enumValuesContainer[enum_list[i].name] = enumStartingLine; class_desc->push_font(doc_code_font); class_desc->push_color(headline_color); @@ -1200,6 +1205,9 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) { class_desc->add_newline(); } + if (cd.name == "@GlobalScope") + enum_values_line[E->key()] = enumValuesContainer; + class_desc->pop(); class_desc->add_newline(); @@ -1485,21 +1493,32 @@ void EditorHelp::_help_callback(const String &p_topic) { if (method_line.has(name)) line = method_line[name]; } else if (what == "class_property") { - if (property_line.has(name)) line = property_line[name]; } else if (what == "class_enum") { - if (enum_line.has(name)) line = enum_line[name]; } else if (what == "class_theme_item") { - if (theme_property_line.has(name)) line = theme_property_line[name]; } else if (what == "class_constant") { - if (constant_line.has(name)) line = constant_line[name]; + } else if (what == "class_global") { + if (constant_line.has(name)) + line = constant_line[name]; + else { + Map<String, Map<String, int> >::Element *iter = enum_values_line.front(); + while (true) { + if (iter->value().has(name)) { + line = iter->value()[name]; + break; + } else if (iter == enum_values_line.back()) + break; + else + iter = iter->next(); + } + } } class_desc->call_deferred("scroll_to_line", line); diff --git a/editor/editor_help.h b/editor/editor_help.h index aa84aa611f..0f93e1b55b 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -152,6 +152,7 @@ class EditorHelp : public VBoxContainer { Map<String, int> theme_property_line; Map<String, int> constant_line; Map<String, int> enum_line; + Map<String, Map<String, int> > enum_values_line; int description_line; RichTextLabel *class_desc; diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index e301d12214..158eedfb0f 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -88,6 +88,7 @@ void EditorLog::_notification(int p_what) { void EditorLog::_clear_request() { log->clear(); + tool_button->set_icon(Ref<Texture>()); } void EditorLog::clear() { @@ -103,9 +104,7 @@ void EditorLog::add_message(const String &p_msg, bool p_error) { Ref<Texture> icon = get_icon("Error", "EditorIcons"); log->add_image(icon); log->add_text(" "); - //button->set_icon(icon); - } else { - //button->set_icon(Ref<Texture>()); + tool_button->set_icon(icon); } log->add_text(p_msg); @@ -115,6 +114,10 @@ void EditorLog::add_message(const String &p_msg, bool p_error) { log->pop(); } +void EditorLog::set_tool_button(ToolButton *p_tool_button) { + tool_button = p_tool_button; +} + /* void EditorLog::_dragged(const Point2& p_ofs) { diff --git a/editor/editor_log.h b/editor/editor_log.h index 42137f71cc..f9bc82de7d 100644 --- a/editor/editor_log.h +++ b/editor/editor_log.h @@ -51,6 +51,7 @@ class EditorLog : public VBoxContainer { RichTextLabel *log; HBoxContainer *title_hb; //PaneDrag *pd; + ToolButton *tool_button; static void _error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type); @@ -68,6 +69,7 @@ protected: public: void add_message(const String &p_msg, bool p_error = false); + void set_tool_button(ToolButton *p_tool_button); void deinit(); void clear(); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 3ef6d65ab4..0bca78b493 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -99,6 +99,7 @@ #include "editor/plugins/script_text_editor.h" #include "editor/plugins/shader_editor_plugin.h" #include "editor/plugins/shader_graph_editor_plugin.h" +#include "editor/plugins/skeleton_2d_editor_plugin.h" #include "editor/plugins/spatial_editor_plugin.h" #include "editor/plugins/sprite_editor_plugin.h" #include "editor/plugins/sprite_frames_editor_plugin.h" @@ -189,6 +190,8 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; if (k.is_valid() && k->is_pressed() && !k->is_echo() && !gui_base->get_viewport()->gui_has_modal_stack()) { + EditorPlugin *old_editor = editor_plugin_screen; + if (ED_IS_SHORTCUT("editor/next_tab", p_event)) { int next_tab = editor_data.get_edited_scene() + 1; next_tab %= editor_data.get_edited_scene_count(); @@ -224,6 +227,10 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) { _bottom_panel_switch(false, i); } } + + if (old_editor != editor_plugin_screen) { + get_tree()->set_input_as_handled(); + } } } @@ -348,14 +355,20 @@ void EditorNode::_notification(int p_what) { // update_icons for (int i = 0; i < singleton->main_editor_buttons.size(); i++) { - Ref<Texture> icon = singleton->main_editor_buttons[i]->get_icon(); + + ToolButton *tb = singleton->main_editor_buttons[i]; + EditorPlugin *p_editor = singleton->editor_table[i]; + Ref<Texture> icon = p_editor->get_icon(); if (icon.is_valid()) { - main_editor_buttons[i]->set_icon(icon); - } else if (singleton->gui_base->has_icon(singleton->main_editor_buttons[i]->get_name(), "EditorIcons")) { - main_editor_buttons[i]->set_icon(gui_base->get_icon(singleton->main_editor_buttons[i]->get_name(), "EditorIcons")); + tb->set_icon(icon); + } else if (singleton->gui_base->has_icon(p_editor->get_name(), "EditorIcons")) { + tb->set_icon(singleton->gui_base->get_icon(p_editor->get_name(), "EditorIcons")); } } + + _build_icon_type_cache(); + play_button->set_icon(gui_base->get_icon("MainPlay", "EditorIcons")); play_scene_button->set_icon(gui_base->get_icon("PlayScene", "EditorIcons")); play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom", "EditorIcons")); @@ -381,6 +394,15 @@ void EditorNode::_notification(int p_what) { dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons")); dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); update_menu->set_icon(gui_base->get_icon("Progress1", "EditorIcons")); + + PopupMenu *p = help_menu->get_popup(); + p->set_item_icon(p->get_item_index(HELP_CLASSES), gui_base->get_icon("ClassList", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_SEARCH), gui_base->get_icon("HelpSearch", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_DOCS), gui_base->get_icon("Instance", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_QA), gui_base->get_icon("Instance", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_ISSUES), gui_base->get_icon("Instance", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_COMMUNITY), gui_base->get_icon("Instance", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_ABOUT), gui_base->get_icon("Godot", "EditorIcons")); } if (p_what == Control::NOTIFICATION_RESIZED) { @@ -448,24 +470,28 @@ void EditorNode::_fs_changed() { } if (preset.is_null()) { String err = "Unknown export preset: " + export_defer.preset; - ERR_PRINT(err.utf8().get_data()); + ERR_PRINTS(err); } else { Ref<EditorExportPlatform> platform = preset->get_platform(); if (platform.is_null()) { String err = "Preset \"" + export_defer.preset + "\" doesn't have a platform."; - ERR_PRINT(err.utf8().get_data()); + ERR_PRINTS(err); } else { // ensures export_project does not loop infinitely, because notifications may // come during the export export_defer.preset = ""; + Error err; if (!preset->is_runnable() && (export_defer.path.ends_with(".pck") || export_defer.path.ends_with(".zip"))) { if (export_defer.path.ends_with(".zip")) { - platform->save_zip(preset, export_defer.path); + err = platform->save_zip(preset, export_defer.path); } else if (export_defer.path.ends_with(".pck")) { - platform->save_pack(preset, export_defer.path); + err = platform->save_pack(preset, export_defer.path); } } else { - platform->export_project(preset, export_defer.debug, export_defer.path, /*p_flags*/ 0); + err = platform->export_project(preset, export_defer.debug, export_defer.path, /*p_flags*/ 0); + } + if (err != OK) { + ERR_PRINTS(vformat(TTR("Project export failed with error code %d."), (int)err)); } } } @@ -588,6 +614,7 @@ void EditorNode::open_resource(const String &p_type) { void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path) { editor_data.apply_changes_in_editors(); + int flg = 0; if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) flg |= ResourceSaver::FLAG_COMPRESS; @@ -596,6 +623,7 @@ void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const St Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); if (err != OK) { + current_option = -1; accept->set_text(TTR("Error saving resource!")); accept->popup_centered_minsize(); return; @@ -982,6 +1010,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { String file = cache_base + ".png"; + post_process_preview(img); img->save_png(file); } @@ -1071,7 +1100,8 @@ void EditorNode::_save_scene(String p_file, int idx) { void EditorNode::_save_all_scenes() { - for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { + int i = _next_unsaved_scene(true, 0); + while (i != -1) { Node *scene = editor_data.get_edited_scene_root(i); if (scene && scene->get_filename() != "") { if (i != editor_data.get_edited_scene()) @@ -1079,6 +1109,7 @@ void EditorNode::_save_all_scenes() { else _save_scene_with_preview(scene->get_filename()); } // else: ignore new scenes + i = _next_unsaved_scene(true, ++i); } _save_default_environment(); @@ -1193,6 +1224,7 @@ void EditorNode::_dialog_action(String p_file) { Error err = ResourceSaver::save(p_file, ml); if (err) { + current_option = -1; accept->get_ok()->set_text(TTR("I see..")); accept->set_text(TTR("Error saving MeshLibrary!")); accept->popup_centered_minsize(); @@ -1227,6 +1259,7 @@ void EditorNode::_dialog_action(String p_file) { Error err = ResourceSaver::save(p_file, ml); if (err) { + current_option = -1; accept->get_ok()->set_text(TTR("I see..")); accept->set_text(TTR("Error saving TileSet!")); accept->popup_centered_minsize(); @@ -1427,7 +1460,8 @@ void EditorNode::_save_default_environment() { if (fallback.is_valid() && fallback->get_path().is_resource_file()) { Map<RES, bool> processed; _find_and_save_edited_subresources(fallback.ptr(), processed, 0); - save_resource_in_path(fallback, fallback->get_path()); + if (fallback->get_last_modified_time() != fallback->get_import_last_modified_time()) + save_resource_in_path(fallback, fallback->get_path()); } } @@ -1573,7 +1607,8 @@ void EditorNode::_edit_current() { // special case if use of external editor is true if (main_plugin->get_name() == "Script" && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) { - main_plugin->edit(current_obj); + if (!changing_scene) + main_plugin->edit(current_obj); } else if (main_plugin != editor_plugin_screen && (!ScriptEditor::get_singleton() || !ScriptEditor::get_singleton()->is_visible_in_tree() || ScriptEditor::get_singleton()->can_take_away_focus())) { @@ -2096,10 +2131,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { log->add_message("REDO: " + action); } break; - case TOOLS_ORPHAN_RESOURCES: { - - orphan_resources->show(); - } break; case EDIT_REVERT: { @@ -2545,6 +2576,30 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } } +void EditorNode::_tool_menu_option(int p_idx) { + switch (tool_menu->get_item_id(p_idx)) { + case TOOLS_ORPHAN_RESOURCES: { + orphan_resources->show(); + } break; + case TOOLS_CUSTOM: { + if (tool_menu->get_item_submenu(p_idx) == "") { + Array params = tool_menu->get_item_metadata(p_idx); + + Object *handler = ObjectDB::get_instance(params[0]); + String callback = params[1]; + Variant *ud = ¶ms[2]; + Variant::CallError ce; + + handler->call(callback, (const Variant **)&ud, 1, ce); + if (ce.error != Variant::CallError::CALL_OK) { + String err = Variant::get_call_error_text(handler, callback, (const Variant **)&ud, 1, ce); + ERR_PRINTS("Error calling function from tool menu: " + err); + } + } // else it's a submenu so don't do anything. + } break; + } +} + int EditorNode::_next_unsaved_scene(bool p_valid_filename, int p_start) { for (int i = p_start; i < editor_data.get_edited_scene_count(); i++) { @@ -2908,7 +2963,7 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { if (p_state.has("editor_index")) { int index = p_state["editor_index"]; - if (current < 2) { //if currently in spatial/2d, only switch to spatial/2d. if curently in script, stay there + if (current < 2) { //if currently in spatial/2d, only switch to spatial/2d. if currently in script, stay there if (index < 2 || !get_edited_scene()) { _editor_select(index); } @@ -3440,6 +3495,19 @@ Ref<Texture> EditorNode::_file_dialog_get_icon(const String &p_path) { return singleton->icon_type_cache["Object"]; } +void EditorNode::_build_icon_type_cache() { + + List<StringName> tl; + StringName ei = "EditorIcons"; + theme_base->get_theme()->get_icon_list(ei, &tl); + for (List<StringName>::Element *E = tl.front(); E; E = E->next()) { + + if (!ClassDB::class_exists(E->get())) + continue; + icon_type_cache[E->get()] = theme_base->get_theme()->get_icon(E->get(), ei); + } +} + void EditorNode::_file_dialog_register(FileDialog *p_dialog) { singleton->file_dialogs.insert(p_dialog); @@ -4424,6 +4492,45 @@ Variant EditorNode::drag_files_and_dirs(const Vector<String> &p_paths, Control * return drag_data; } +void EditorNode::add_tool_menu_item(const String &p_name, Object *p_handler, const String &p_callback, const Variant &p_ud) { + ERR_FAIL_NULL(p_handler); + int idx = tool_menu->get_item_count(); + tool_menu->add_item(p_name, TOOLS_CUSTOM); + + Array parameters; + parameters.push_back(p_handler->get_instance_id()); + parameters.push_back(p_callback); + parameters.push_back(p_ud); + + tool_menu->set_item_metadata(idx, parameters); +} + +void EditorNode::add_tool_submenu_item(const String &p_name, PopupMenu *p_submenu) { + ERR_FAIL_NULL(p_submenu); + ERR_FAIL_COND(p_submenu->get_parent() != NULL); + + tool_menu->add_child(p_submenu); + tool_menu->add_submenu_item(p_name, p_submenu->get_name(), TOOLS_CUSTOM); +} + +void EditorNode::remove_tool_menu_item(const String &p_name) { + for (int i = 0; i < tool_menu->get_item_count(); i++) { + if (tool_menu->get_item_id(i) != TOOLS_CUSTOM) + continue; + + if (tool_menu->get_item_text(i) == p_name) { + if (tool_menu->get_item_submenu(i) != "") { + Node *n = tool_menu->get_node(tool_menu->get_item_submenu(i)); + tool_menu->remove_child(n); + memdelete(n); + } + tool_menu->remove_item(i); + tool_menu->set_as_minsize(); + return; + } + } +} + void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) { String to_path = ProjectSettings::get_singleton()->globalize_path(get_filesystem_dock()->get_current_path()); @@ -4620,6 +4727,7 @@ Vector<Ref<EditorResourceConversionPlugin> > EditorNode::find_resource_conversio void EditorNode::_bind_methods() { ClassDB::bind_method("_menu_option", &EditorNode::_menu_option); + ClassDB::bind_method("_tool_menu_option", &EditorNode::_tool_menu_option); ClassDB::bind_method("_menu_confirm_current", &EditorNode::_menu_confirm_current); ClassDB::bind_method("_dialog_action", &EditorNode::_dialog_action); ClassDB::bind_method("_resource_selected", &EditorNode::_resource_selected, DEFVAL("")); @@ -4758,18 +4866,43 @@ EditorNode::EditorNode() { FileAccess::set_backup_save(EDITOR_GET("filesystem/on_save/safe_save_on_backup_then_rename")); { - int dpi_mode = EditorSettings::get_singleton()->get("interface/editor/hidpi_mode"); - if (dpi_mode == 0) { - const int screen = OS::get_singleton()->get_current_screen(); - editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0); - } else if (dpi_mode == 1) { - editor_set_scale(0.75); - } else if (dpi_mode == 2) { - editor_set_scale(1.0); - } else if (dpi_mode == 3) { - editor_set_scale(1.5); - } else if (dpi_mode == 4) { - editor_set_scale(2.0); + int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale"); + float custom_display_scale = EditorSettings::get_singleton()->get("interface/editor/custom_display_scale"); + + switch (display_scale) { + case 0: { + // Try applying a suitable display scale automatically + const int screen = OS::get_singleton()->get_current_screen(); + editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0); + } break; + + case 1: { + editor_set_scale(0.75); + } break; + + case 2: { + editor_set_scale(1.0); + } break; + + case 3: { + editor_set_scale(1.25); + } break; + + case 4: { + editor_set_scale(1.5); + } break; + + case 5: { + editor_set_scale(1.75); + } break; + + case 6: { + editor_set_scale(2.0); + } break; + + default: { + editor_set_scale(custom_display_scale); + } break; } } @@ -5131,7 +5264,6 @@ EditorNode::EditorNode() { gui_base->add_child(export_template_manager); about = memnew(EditorAbout); - about->get_logo()->set_texture(gui_base->get_icon("Logo", "EditorIcons")); gui_base->add_child(about); warning = memnew(AcceptDialog); @@ -5194,9 +5326,9 @@ EditorNode::EditorNode() { p->connect("id_pressed", this, "_menu_option"); p->add_item(TTR("Export"), FILE_EXPORT_PROJECT); - PopupMenu *tool_menu = memnew(PopupMenu); + tool_menu = memnew(PopupMenu); tool_menu->set_name("Tools"); - tool_menu->connect("id_pressed", this, "_menu_option"); + tool_menu->connect("index_pressed", this, "_tool_menu_option"); p->add_child(tool_menu); p->add_submenu_item(TTR("Tools"), "Tools"); tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES); @@ -5556,7 +5688,8 @@ EditorNode::EditorNode() { bottom_panel_vb->add_child(bottom_panel_hb); log = memnew(EditorLog); - add_bottom_panel_item(TTR("Output"), log); + ToolButton *output_button = add_bottom_panel_item(TTR("Output"), log); + log->set_tool_button(output_button); old_split_ofs = 0; @@ -5673,6 +5806,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(MeshLibraryEditorPlugin(this))); add_editor_plugin(memnew(StyleBoxEditorPlugin(this))); add_editor_plugin(memnew(SpriteEditorPlugin(this))); + add_editor_plugin(memnew(Skeleton2DEditorPlugin(this))); add_editor_plugin(memnew(ParticlesEditorPlugin(this))); add_editor_plugin(memnew(ResourcePreloaderEditorPlugin(this))); add_editor_plugin(memnew(ItemListEditorPlugin(this))); @@ -5795,17 +5929,7 @@ EditorNode::EditorNode() { EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_fs_changed"); EditorFileSystem::get_singleton()->connect("resources_reimported", this, "_resources_reimported"); - { - List<StringName> tl; - StringName ei = "EditorIcons"; - theme_base->get_theme()->get_icon_list(ei, &tl); - for (List<StringName>::Element *E = tl.front(); E; E = E->next()) { - - if (!ClassDB::class_exists(E->get())) - continue; - icon_type_cache[E->get()] = theme_base->get_theme()->get_icon(E->get(), ei); - } - } + _build_icon_type_cache(); Node::set_human_readable_collision_renaming(true); diff --git a/editor/editor_node.h b/editor/editor_node.h index 6d96c2dea7..90bebffca6 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -141,6 +141,7 @@ private: EDIT_REDO, EDIT_REVERT, TOOLS_ORPHAN_RESOURCES, + TOOLS_CUSTOM, RESOURCE_NEW, RESOURCE_LOAD, RESOURCE_SAVE, @@ -426,6 +427,7 @@ private: void _menu_option(int p_option); void _menu_confirm_current(); void _menu_option_confirm(int p_option, bool p_confirmed); + void _tool_menu_option(int p_idx); void _update_debug_options(); void _property_editor_forward(); @@ -496,6 +498,7 @@ private: Set<EditorFileDialog *> editor_file_dialogs; Map<String, Ref<Texture> > icon_type_cache; + void _build_icon_type_cache(); bool _initializing_addons; Map<String, EditorPlugin *> plugin_addons; @@ -599,21 +602,6 @@ private: static int build_callback_count; static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS]; - bool _initializing_tool_menu; - - struct ToolMenuItem { - String name; - String submenu; - Variant ud; - ObjectID handler; - String callback; - }; - - Vector<ToolMenuItem> tool_menu_items; - - void _tool_menu_insert_item(const ToolMenuItem &p_item); - void _rebuild_tool_menu() const; - bool _dimming; float _dim_time; Timer *_dim_timer; diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 31d0bfa8a9..4f38c0188d 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -429,21 +429,18 @@ void EditorPlugin::remove_control_from_container(CustomControlContainer p_locati } void EditorPlugin::add_tool_menu_item(const String &p_name, Object *p_handler, const String &p_callback, const Variant &p_ud) { - - //EditorNode::get_singleton()->add_tool_menu_item(p_name, p_handler, p_callback, p_ud); + EditorNode::get_singleton()->add_tool_menu_item(p_name, p_handler, p_callback, p_ud); } void EditorPlugin::add_tool_submenu_item(const String &p_name, Object *p_submenu) { - ERR_FAIL_NULL(p_submenu); PopupMenu *submenu = Object::cast_to<PopupMenu>(p_submenu); ERR_FAIL_NULL(submenu); - //EditorNode::get_singleton()->add_tool_submenu_item(p_name, submenu); + EditorNode::get_singleton()->add_tool_submenu_item(p_name, submenu); } void EditorPlugin::remove_tool_menu_item(const String &p_name) { - - //EditorNode::get_singleton()->remove_tool_menu_item(p_name); + EditorNode::get_singleton()->remove_tool_menu_item(p_name); } void EditorPlugin::set_input_event_forwarding_always_enabled() { @@ -707,9 +704,9 @@ void EditorPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("remove_control_from_docks", "control"), &EditorPlugin::remove_control_from_docks); ClassDB::bind_method(D_METHOD("remove_control_from_bottom_panel", "control"), &EditorPlugin::remove_control_from_bottom_panel); ClassDB::bind_method(D_METHOD("remove_control_from_container", "container", "control"), &EditorPlugin::remove_control_from_container); - //ClassDB::bind_method(D_METHOD("add_tool_menu_item", "name", "handler", "callback", "ud"),&EditorPlugin::add_tool_menu_item,DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("add_tool_menu_item", "name", "handler", "callback", "ud"), &EditorPlugin::add_tool_menu_item, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("add_tool_submenu_item", "name", "submenu"), &EditorPlugin::add_tool_submenu_item); - //ClassDB::bind_method(D_METHOD("remove_tool_menu_item", "name"),&EditorPlugin::remove_tool_menu_item); + ClassDB::bind_method(D_METHOD("remove_tool_menu_item", "name"), &EditorPlugin::remove_tool_menu_item); ClassDB::bind_method(D_METHOD("add_custom_type", "type", "base", "script", "icon"), &EditorPlugin::add_custom_type); ClassDB::bind_method(D_METHOD("remove_custom_type", "type"), &EditorPlugin::remove_custom_type); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 29363e29c1..85f6d99c67 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -283,13 +283,19 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["interface/editor/editor_language"] = PropertyInfo(Variant::STRING, "interface/editor/editor_language", PROPERTY_HINT_ENUM, lang_hint, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); } - _initial_set("interface/editor/hidpi_mode", 0); - hints["interface/editor/hidpi_mode"] = PropertyInfo(Variant::INT, "interface/editor/hidpi_mode", PROPERTY_HINT_ENUM, "Auto,VeryLoDPI,LoDPI,MidDPI,HiDPI", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); + _initial_set("interface/editor/display_scale", 0); + hints["interface/editor/display_scale"] = PropertyInfo(Variant::INT, "interface/editor/display_scale", PROPERTY_HINT_ENUM, "Auto,75%,100%,125%,150%,175%,200%,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); + _initial_set("interface/editor/custom_display_scale", 1.0f); + hints["interface/editor/custom_display_scale"] = PropertyInfo(Variant::REAL, "interface/editor/custom_display_scale", PROPERTY_HINT_RANGE, "0.75,3,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/scene_tabs/show_script_button", false); _initial_set("interface/editor/main_font_size", 14); hints["interface/editor/main_font_size"] = PropertyInfo(Variant::INT, "interface/editor/main_font_size", PROPERTY_HINT_RANGE, "10,40,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/editor/code_font_size", 14); hints["interface/editor/code_font_size"] = PropertyInfo(Variant::INT, "interface/editor/code_font_size", PROPERTY_HINT_RANGE, "8,96,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); + _initial_set("interface/editor/main_font_hinting", 2); + hints["interface/editor/main_font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/main_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); + _initial_set("interface/editor/code_font_hinting", 2); + hints["interface/editor/code_font_hinting"] = PropertyInfo(Variant::INT, "interface/editor/code_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/editor/main_font", ""); hints["interface/editor/main_font"] = PropertyInfo(Variant::STRING, "interface/editor/main_font", PROPERTY_HINT_GLOBAL_FILE, "*.ttf,*.otf", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("interface/editor/code_font", ""); @@ -403,6 +409,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { // navigation _initial_set("editors/3d/navigation/navigation_scheme", 0); + _initial_set("editors/3d/navigation/invert_y-axis", false); hints["editors/3d/navigation/navigation_scheme"] = PropertyInfo(Variant::INT, "editors/3d/navigation/navigation_scheme", PROPERTY_HINT_ENUM, "Godot,Maya,Modo"); _initial_set("editors/3d/navigation/zoom_style", 0); hints["editors/3d/navigation/zoom_style"] = PropertyInfo(Variant::INT, "editors/3d/navigation/zoom_style", PROPERTY_HINT_ENUM, "Vertical, Horizontal"); @@ -959,11 +966,8 @@ void EditorSettings::save() { Error err = ResourceSaver::save(singleton->config_file_path, singleton); if (err != OK) { - ERR_PRINT("Can't Save!"); - return; - } - - if (OS::get_singleton()->is_stdout_verbose()) { + ERR_PRINTS("Error saving editor settings to " + singleton->config_file_path); + } else if (OS::get_singleton()->is_stdout_verbose()) { print_line("EditorSettings Save OK!"); } } diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 096a60afa3..3582379e34 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -626,8 +626,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_color_disabled", "PopupMenu", font_color_disabled); theme->set_icon("checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons")); theme->set_icon("unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons")); - theme->set_icon("radio_checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons")); - theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons")); + theme->set_icon("radio_checked", "PopupMenu", theme->get_icon("GuiRadioChecked", "EditorIcons")); + theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon("GuiRadioUnchecked", "EditorIcons")); theme->set_icon("submenu", "PopupMenu", theme->get_icon("ArrowRight", "EditorIcons")); theme->set_icon("visibility_hidden", "PopupMenu", theme->get_icon("GuiVisibilityHidden", "EditorIcons")); theme->set_icon("visibility_visible", "PopupMenu", theme->get_icon("GuiVisibilityVisible", "EditorIcons")); @@ -1139,7 +1139,9 @@ Ref<Theme> create_custom_theme(const Ref<Theme> p_theme) { String custom_theme = EditorSettings::get_singleton()->get("interface/theme/custom_theme"); if (custom_theme != "") { theme = ResourceLoader::load(custom_theme); - } else { + } + + if (!theme.is_valid()) { theme = create_editor_theme(p_theme); } diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp index 41b016bdca..101deb9126 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export_template_manager.cpp @@ -70,7 +70,7 @@ void ExportTemplateManager::_update_template_list() { memdelete(d); - String current_version = itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + VERSION_STATUS + VERSION_MODULE_CONFIG; + String current_version = VERSION_FULL_CONFIG; Label *current = memnew(Label); current->set_h_size_flags(SIZE_EXPAND_FILL); @@ -217,25 +217,15 @@ void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_ data_str.parse_utf8((const char *)data.ptr(), data.size()); data_str = data_str.strip_edges(); - if (data_str.get_slice_count("-") != 2 || data_str.get_slice_count(".") != 2) { - EditorNode::get_singleton()->show_warning(TTR("Invalid version.txt format inside templates.")); + // Version number should be of the form major.minor[.patch].status[.module_config] + // so it can in theory have 3 or more slices. + if (data_str.get_slice_count(".") < 3) { + EditorNode::get_singleton()->show_warning(vformat(TTR("Invalid version.txt format inside templates: %s."), data_str)); unzClose(pkg); return; } - String ver = data_str.get_slice("-", 0); - - int major = ver.get_slice(".", 0).to_int(); - int minor = ver.get_slice(".", 1).to_int(); - String rev = data_str.get_slice("-", 1); - - if (!rev.is_valid_identifier()) { - EditorNode::get_singleton()->show_warning(TTR("Invalid version.txt format inside templates. Revision is not a valid identifier.")); - unzClose(pkg); - return; - } - - version = itos(major) + "." + itos(minor) + "-" + rev; + version = data_str; } fc++; diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 0be3bb86c7..d5783c9b1a 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -918,7 +918,7 @@ void FileSystemDock::_make_dir_confirm() { if (dir_name.length() == 0) { EditorNode::get_singleton()->show_warning(TTR("No name provided")); return; - } else if (dir_name.find("/") != -1 || dir_name.find("\\") != -1 || dir_name.find(":") != -1) { + } else if (dir_name.find("/") != -1 || dir_name.find("\\") != -1 || dir_name.find(":") != -1 || dir_name.ends_with(".")) { EditorNode::get_singleton()->show_warning(TTR("Provided name contains invalid characters")); return; } @@ -1034,8 +1034,19 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path) { void FileSystemDock::_file_option(int p_option) { switch (p_option) { case FILE_SHOW_IN_EXPLORER: { - String dir = ProjectSettings::get_singleton()->globalize_path(this->path); - OS::get_singleton()->shell_open(String("file://") + dir); + + String path = this->path; + + // first try to grab directory from selected file, so that it works for searched files + int idx = files->get_current(); + + if (idx >= 0 && idx < files->get_item_count()) { + path = files->get_item_metadata(idx); + path = path.get_base_dir(); + } + + path = ProjectSettings::get_singleton()->globalize_path(path); + OS::get_singleton()->shell_open(String("file://") + path); } break; case FILE_OPEN: { for (int i = 0; i < files->get_item_count(); i++) { @@ -1660,6 +1671,8 @@ void FileSystemDock::_files_gui_input(Ref<InputEvent> p_event) { _file_option(FILE_COPY_PATH); } else if (ED_IS_SHORTCUT("filesystem_dock/delete", p_event)) { _file_option(FILE_REMOVE); + } else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) { + _file_option(FILE_RENAME); } } } @@ -1770,6 +1783,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { ED_SHORTCUT("filesystem_dock/copy_path", TTR("Copy Path"), KEY_MASK_CMD | KEY_C); ED_SHORTCUT("filesystem_dock/duplicate", TTR("Duplicate..."), KEY_MASK_CMD | KEY_D); ED_SHORTCUT("filesystem_dock/delete", TTR("Delete"), KEY_DELETE); + ED_SHORTCUT("filesystem_dock/rename", TTR("Rename")); HBoxContainer *toolbar_hbc = memnew(HBoxContainer); add_child(toolbar_hbc); diff --git a/editor/icons/SCsub b/editor/icons/SCsub index 64992a9f90..7f94073e01 100644 --- a/editor/icons/SCsub +++ b/editor/icons/SCsub @@ -82,10 +82,9 @@ def make_editor_icons_action(target, source, env): s.write("#endif\n") + with open(dst, "w") as f: + f.write(s.getvalue()) - f = open(dst, "w") - f.write(s.getvalue()) - f.close() s.close() icons_string.close() diff --git a/editor/icons/icon_action_copy.svg b/editor/icons/icon_action_copy.svg new file mode 100644 index 0000000000..d5da233bc9 --- /dev/null +++ b/editor/icons/icon_action_copy.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m2 1c-0.554 0-1 0.446-1 1v9c0 0.554 0.446 1 1 1h1v-9h9v-1c0-0.554-0.446-1-1-1h-9zm3 3c-0.554 0-1 0.446-1 1v9c0 0.554 0.446 1 1 1h9c0.554 0 1-0.446 1-1v-9c0-0.554-0.446-1-1-1h-9zm1 2h7v7h-7v-7z" fill="#e0e0e0"/> +</svg> diff --git a/editor/icons/icon_action_cut.svg b/editor/icons/icon_action_cut.svg new file mode 100644 index 0000000000..776ca3a4c4 --- /dev/null +++ b/editor/icons/icon_action_cut.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m3.6348 0.50977c-2.9641 2.866 0.53553 8.9289 2.7676 8.7949l0.44141 0.76562-0.56445 0.97852a3 3 0 0 0 -2.2793 -1.0488 3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 2.5938 -1.502l0.0039062 0.001953 1.4023-2.4277 1.4023 2.4277 0.0019531-0.001953a3 3 0 0 0 2.5957 1.502 3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3 3 3 0 0 0 -2.2773 1.0527l-0.56641-0.98242 0.44141-0.76562c2.2321 0.13397 5.7317-5.9289 2.7676-8.7949l-4.3652 7.5605-4.3652-7.5605zm0.36523 11.49a1 1 0 0 1 1 1 1 1 0 0 1 -0.12305 0.47852l-0.011719 0.021484a1 1 0 0 1 -0.86523 0.5 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm8 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#e0e0e0"/> +</svg> diff --git a/editor/icons/icon_action_paste.svg b/editor/icons/icon_action_paste.svg new file mode 100644 index 0000000000..b71e5531df --- /dev/null +++ b/editor/icons/icon_action_paste.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m8 1c-1.3045 0-2.4033 0.8372-2.8164 2h-3.1836c-0.554 0-1 0.446-1 1v10c0 0.554 0.446 1 1 1h12c0.554 0 1-0.446 1-1v-10c0-0.554-0.446-1-1-1h-3.1836c-0.41312-1.1628-1.5119-2-2.8164-2zm0 2a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-5 2h2v2h6v-2h2v8h-10v-8z" fill="#e0e0e0"/> +</svg> diff --git a/editor/icons/icon_add_split.svg b/editor/icons/icon_add_split.svg new file mode 100644 index 0000000000..6cfd419e7f --- /dev/null +++ b/editor/icons/icon_add_split.svg @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg4" + sodipodi:docname="icon_add_split.svg" + inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="3066" + inkscape:window-height="1689" + id="namedview6" + showgrid="false" + inkscape:zoom="41.7193" + inkscape:cx="7.7924561" + inkscape:cy="6.0148972" + inkscape:window-x="134" + inkscape:window-y="55" + inkscape:window-maximized="1" + inkscape:current-layer="svg4" /> + <rect + style="fill:#800000" + id="rect12" + width="1.8456686" + height="2.0853658" + x="0.62321275" + y="6.9394455" /> + <rect + style="fill:#800000" + id="rect14" + width="1.6299411" + height="1.9894869" + x="12.488225" + y="7.1791425" /> + <rect + style="fill:#e9afaf" + id="rect16" + width="10.067283" + height="0.69512194" + x="2.492851" + y="7.7304463" /> +</svg> diff --git a/editor/icons/icon_array_mesh.svg b/editor/icons/icon_array_mesh.svg index 867fc95b0c..7c086e1a44 100644 --- a/editor/icons/icon_array_mesh.svg +++ b/editor/icons/icon_array_mesh.svg @@ -1,3 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm10 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-2 7v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2zm-8 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> +<path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm10 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-2 7v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2zm-8 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" fill="#ffd684"/> </svg> diff --git a/editor/icons/icon_asset_lib.svg b/editor/icons/icon_asset_lib.svg index fcd670817d..1348c491fc 100644 --- a/editor/icons/icon_asset_lib.svg +++ b/editor/icons/icon_asset_lib.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m8 1c-1.6569 0-3 1.3431-3 3v2h-4v7c0 1.108 0.89199 2 2 2h10c1.108 0 2-0.89199 2-2v-7h-4v-2c0-1.6569-1.3431-3-3-3zm0 2c0.55228 0 1 0.44772 1 1v2h-2v-2c0-0.55228 0.44772-1 1-1z" fill="#e0e0e0"/> -</g> +<path d="m8 1c-1.6569 0-3 1.3431-3 3v2h-4v7c0 1.108 0.89199 2 2 2h10c1.108 0 2-0.89199 2-2v-7h-4v-2c0-1.6569-1.3431-3-3-3zm0 2c0.55228 0 1 0.44772 1 1v2h-2v-2c0-0.55228 0.44772-1 1-1z" fill="#e0e0e0"/> </svg> diff --git a/editor/icons/icon_capsule_mesh.svg b/editor/icons/icon_capsule_mesh.svg index bc736200a4..c375e6adfb 100644 --- a/editor/icons/icon_capsule_mesh.svg +++ b/editor/icons/icon_capsule_mesh.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path d="m8 1037.4c-2.7527 0-5 2.2419-5 4.9903v4.0175c0 2.7484 2.2473 4.9922 5 4.9922 2.7527 0 5-2.2438 5-4.9922v-4.0175c0-2.7484-2.2473-4.9903-5-4.9903zm-1.0059 2.1264v4.8576c-0.66556-0.1047-1.2973-0.372-1.9941-0.6618v-1.3222c0-1.3474 0.79838-2.4648 1.9941-2.8736zm2.0118 0c1.1957 0.4088 1.9941 1.5262 1.9941 2.8736v1.3451c-0.68406 0.3054-1.3142 0.5732-1.9941 0.6663zm-4.0059 6.334c0.67836 0.2231 1.3126 0.447 1.9941 0.5264v2.8848c-1.1957-0.4092-1.9941-1.5242-1.9941-2.8716zm6 0.03v0.5094c0 1.3474-0.79838 2.4619-1.9941 2.8711v-2.8711c0.68606-0.068 1.3207-0.2828 1.9941-0.5094z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> -</g> +<path d="m8 1c-2.7527 0-5 2.2419-5 4.9903v4.0175c0 2.7484 2.2473 4.9922 5 4.9922 2.7527 0 5-2.2438 5-4.9922v-4.0175c0-2.7484-2.2473-4.9903-5-4.9903zm-1.0059 2.1264v4.8576c-0.66556-0.1047-1.2973-0.372-1.9941-0.6618v-1.3222c0-1.3474 0.79838-2.4648 1.9941-2.8736zm2.0118 0c1.1957 0.4088 1.9941 1.5262 1.9941 2.8736v1.3451c-0.68406 0.3054-1.3142 0.5732-1.9941 0.6663zm-4.0059 6.334c0.67836 0.2231 1.3126 0.447 1.9941 0.5264v2.8848c-1.1957-0.4092-1.9941-1.5242-1.9941-2.8716zm6 0.03v0.5094c0 1.3474-0.79838 2.4619-1.9941 2.8711v-2.8711c0.68606-0.068 1.3207-0.2828 1.9941-0.5094z" fill="#ffd684"/> </svg> diff --git a/editor/icons/icon_cone_twist_joint.svg b/editor/icons/icon_cone_twist_joint.svg index c9d92d6537..8d869fa1d5 100644 --- a/editor/icons/icon_cone_twist_joint.svg +++ b/editor/icons/icon_cone_twist_joint.svg @@ -1,7 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)" fill="none" stroke="#fc9c9c" stroke-linecap="round" stroke-width="2"> -<path transform="translate(0 1036.4)" d="m8 2l-6 9a6 3 0 0 0 3 2.5977 6 3 0 0 0 6 0 6 3 0 0 0 3 -2.5977l-6-9z" stroke-linejoin="round"/> -<ellipse cx="8" cy="1047.4" rx="6" ry="3" stroke-linejoin="round"/> -<path d="m8 1039.4v8"/> +<g transform="translate(0 -1036.4)"> +<path transform="translate(0 1036.4)" d="m7.9824 1a1.0001 1.0001 0 0 0 -0.81445 0.44531l-4.7012 7.0527c-0.80117 0.58197-1.3801 1.3563-1.4492 2.3145a1.0001 1.0001 0 0 0 -0.017578 0.1875c0 0.21449 0.033976 0.41628 0.082031 0.61328 0.0071983 0.028314 0.015306 0.055972 0.023438 0.083985 0.053631 0.19149 0.1274 0.37452 0.2207 0.54883 0.19678 0.36764 0.47105 0.69651 0.80273 0.98633 0.007988 0.007025 0.013442 0.016473 0.021484 0.023437 0.016953 0.014679 0.03747 0.026532 0.054688 0.041016 0.10299 0.086112 0.21259 0.16531 0.32422 0.24414 0.23883 0.16992 0.49083 0.33075 0.76953 0.4707 0.0025295 0.00127 0.0052799 0.002638 0.0078125 0.003906 0.001313 6.58e-4 0.0025928 0.001296 0.0039063 0.001953 0.0085785 0.00429 0.018732 0.007456 0.027344 0.011719 0.26499 0.13103 0.55174 0.24596 0.84961 0.35156 0.10487 0.037634 0.21202 0.071147 0.32031 0.10547 0.072945 0.022902 0.1402 0.050715 0.21484 0.072266 0.16777 0.04843 0.34161 0.086385 0.51367 0.12695 0.093562 0.021905 0.18185 0.048745 0.27734 0.068359 0.010733 0.002205 0.022447 0.003684 0.033203 0.00586 0.34623 0.071177 0.69974 0.12196 1.0566 0.16211 0.057889 0.006228 0.11544 0.01213 0.17383 0.017578 0.81052 0.079498 1.6348 0.079498 2.4453 0 0.058387-0.005448 0.11594-0.01135 0.17383-0.017578 0.3569-0.040146 0.71041-0.090932 1.0566-0.16211 0.010948-0.002251 0.022269-0.003578 0.033203-0.00586 0.095491-0.019614 0.18378-0.046454 0.27734-0.068359 0.17206-0.040568 0.3459-0.078523 0.51367-0.12695 0.074642-0.021551 0.1419-0.049364 0.21484-0.072266 0.10829-0.034322 0.21544-0.067835 0.32031-0.10547 0.29787-0.1056 0.58462-0.22053 0.84961-0.35156 0.009951-0.00492 0.021348-0.008715 0.03125-0.013672 0.002626-0.001315 0.005189-0.002588 0.007813-0.003906 0.2787-0.13995 0.5307-0.30078 0.76953-0.4707 0.11163-0.07883 0.22123-0.15803 0.32422-0.24414 0.017218-0.014484 0.037734-0.026337 0.054687-0.041016 0.008042-0.006964 0.013497-0.016412 0.021485-0.023437 0.33169-0.28982 0.60596-0.61869 0.80273-0.98633 0.093299-0.17431 0.16707-0.35733 0.2207-0.54883 0.008132-0.028013 0.016239-0.055671 0.023438-0.083985 0.048055-0.197 0.082031-0.39879 0.082031-0.61328a1.0001 1.0001 0 0 0 -0.017578 -0.18164 1.0001 1.0001 0 0 0 -0.001953 -0.017578c-0.073081-0.95265-0.64941-1.7232-1.4473-2.3027l-4.7012-7.0527a1.0001 1.0001 0 0 0 -0.84961 -0.44531zm-0.98242 4.3027v1.7461c-0.43911 0.033461-0.86366 0.087835-1.2734 0.16406l1.2734-1.9102zm2 0l1.2734 1.9102c-0.40978-0.076228-0.83432-0.1306-1.2734-0.16406v-1.7461zm-2 3.748v1.9492a1.0001 1.0001 0 1 0 2 0v-1.9492c1.1126 0.10487 2.0951 0.37277 2.7949 0.72266 0.12146 0.060728 0.20622 0.12218 0.30664 0.18359l0.80078 1.2012c-0.032965 0.14677-0.089654 0.30658-0.30469 0.51758-0.051464 0.049149-0.10034 0.098137-0.16406 0.14844-0.045193 0.035312-0.091373 0.070148-0.14258 0.10547-0.11245 0.07827-0.24511 0.15838-0.39062 0.23633-0.075428 0.040204-0.1553 0.078371-0.23828 0.11719-0.16195 0.075482-0.33452 0.14662-0.52148 0.21289-0.070588 0.025324-0.14454 0.048409-0.21875 0.072265-0.23425 0.074473-0.48077 0.14392-0.74414 0.20117-0.021343 0.004579-0.041038 0.011189-0.0625 0.015625-0.2559 0.05368-0.53101 0.090517-0.80859 0.125-0.856 0.10229-1.7573 0.10229-2.6133 0-0.27759-0.034483-0.5527-0.07132-0.80859-0.125-0.021462-0.004436-0.041156-0.011046-0.0625-0.015625-0.26337-0.057254-0.50989-0.1267-0.74414-0.20117-0.074211-0.023856-0.14816-0.046941-0.21875-0.072265-0.18697-0.066266-0.35954-0.13741-0.52148-0.21289-0.082979-0.038816-0.16285-0.076983-0.23828-0.11719-0.14552-0.077951-0.27818-0.15806-0.39062-0.23633-0.051205-0.035321-0.097386-0.070157-0.14258-0.10547-0.06372-0.050301-0.1126-0.099289-0.16406-0.14844-0.21503-0.21099-0.27173-0.37081-0.30469-0.51758l0.80078-1.2012c0.10043-0.061415 0.18518-0.12287 0.30664-0.18359 0.69978-0.34989 1.6823-0.61778 2.7949-0.72266z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fc9c9c" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> </g> </svg> diff --git a/editor/icons/icon_cube_mesh.svg b/editor/icons/icon_cube_mesh.svg index 45275216ab..d1897dd710 100644 --- a/editor/icons/icon_cube_mesh.svg +++ b/editor/icons/icon_cube_mesh.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 14.999999 14.999999" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1037.4)"> -<path d="m7.5 1038.2-6.5625 3.2804v6.772l6.5625 3.2804 6.5625-3.2804v-6.772zm0 1.9831 3.6926 1.8463-3.6926 1.8463-3.6926-1.8463zm-4.7889 3.2804 3.9022 1.9502v3.6944l-3.9022-1.952zm9.5779 0v3.6926l-3.9022 1.952v-3.6944z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> -</g> +<path transform="scale(.9375)" d="m8 0.88867-7 3.5v7.2227l7 3.5 7-3.5v-7.2227zm0 2.1152 3.9395 1.9707-3.9395 1.9688-3.9395-1.9688zm-5 3.5527 4 2v3.9414l-4-2.002zm10 0v3.9395l-4 2.002v-3.9414z" fill="#ffd684" stroke-width="1.0667"/> </svg> diff --git a/editor/icons/icon_cylinder_mesh.svg b/editor/icons/icon_cylinder_mesh.svg index 92a93ec220..21b5fc144b 100644 --- a/editor/icons/icon_cylinder_mesh.svg +++ b/editor/icons/icon_cylinder_mesh.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 14.999999 14.999999" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1037.4)"> -<path transform="matrix(.9375 0 0 .9375 0 1037.4)" d="m8 1c-1.7469 0-3.328 0.22648-4.5586 0.63672-0.61528 0.20512-1.1471 0.45187-1.5898 0.80078s-0.85156 0.88101-0.85156 1.5625v8c0 0.68149 0.40884 1.2155 0.85156 1.5645s0.97457 0.59577 1.5898 0.80078c1.2306 0.41024 2.8117 0.63477 4.5586 0.63477s3.328-0.22453 4.5586-0.63477c0.61527-0.20501 1.1471-0.45187 1.5898-0.80078 0.44272-0.34891 0.85156-0.88296 0.85156-1.5645v-8c0-0.68149-0.40884-1.2136-0.85156-1.5625-0.44272-0.34891-0.97457-0.59566-1.5898-0.80078-1.2306-0.41024-2.8117-0.63672-4.5586-0.63672zm0 2c1.5668 0 2.9867 0.22145 3.9277 0.53516 0.46368 0.15456 0.80138 0.33741 0.96875 0.4668-0.16752 0.12928-0.50546 0.3105-0.96875 0.46484-0.94102 0.31371-2.361 0.5332-3.9277 0.5332s-2.9867-0.2195-3.9277-0.5332c-0.46329-0.15435-0.80123-0.33556-0.96875-0.46484 0.16737-0.12939 0.50507-0.31224 0.96875-0.4668 0.94102-0.31371 2.361-0.53516 3.9277-0.53516zm-5 3.1875c0.1468 0.059071 0.2835 0.12512 0.44141 0.17773 1.2306 0.41024 2.8117 0.63477 4.5586 0.63477s3.328-0.22453 4.5586-0.63477c0.15791-0.052617 0.29461-0.11866 0.44141-0.17773v5.8125c-0.16752 0.12928-0.60898 0.31245-1.0723 0.4668-0.94102 0.31371-2.361 0.5332-3.9277 0.5332s-2.9867-0.2195-3.9277-0.5332c-0.46329-0.15435-0.90474-0.33752-1.0723-0.4668z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> -</g> +<path d="m7.5 0.9375c-1.6377 0-3.12 0.2123-4.2737 0.5969-0.57682 0.1923-1.0754 0.4237-1.4905 0.7508-0.41505 0.3271-0.79834 0.8259-0.79834 1.4648v7.5c0 0.6389 0.38329 1.1396 0.79834 1.4667 0.41505 0.3271 0.91366 0.5585 1.4905 0.7507 1.1536 0.3846 2.6359 0.5951 4.2737 0.5951s3.12-0.2105 4.2737-0.5951c0.57682-0.1922 1.0754-0.4236 1.4905-0.7507 0.41505-0.3271 0.79834-0.8278 0.79834-1.4667v-7.5c0-0.6389-0.38329-1.1377-0.79834-1.4648-0.41505-0.3271-0.91366-0.5585-1.4905-0.7508-1.1536-0.3846-2.6359-0.5969-4.2737-0.5969zm0 1.875c1.4689 0 2.8 0.2076 3.6823 0.5017 0.4347 0.1449 0.7513 0.3163 0.9082 0.4376-0.15705 0.1212-0.47387 0.2911-0.9082 0.4358-0.88221 0.2941-2.2134 0.4999-3.6823 0.4999s-2.8-0.2058-3.6823-0.4999c-0.43433-0.1447-0.75115-0.3146-0.9082-0.4358 0.15691-0.1213 0.47351-0.2927 0.9082-0.4376 0.88221-0.2941 2.2134-0.5017 3.6823-0.5017zm-4.6875 2.9883c0.13762 0.055 0.26578 0.1173 0.41382 0.1666 1.1536 0.3846 2.6359 0.5951 4.2737 0.5951s3.12-0.2105 4.2737-0.5951c0.14804-0.049 0.2762-0.1112 0.41382-0.1666v5.4492c-0.15705 0.1212-0.57092 0.2929-1.0052 0.4376-0.88221 0.2941-2.2134 0.4999-3.6823 0.4999s-2.8-0.2058-3.6823-0.4999c-0.43433-0.1447-0.8482-0.3164-1.0052-0.4376z" fill="#ffd684"/> </svg> diff --git a/editor/icons/icon_delete_split.svg b/editor/icons/icon_delete_split.svg new file mode 100644 index 0000000000..c24f7449d6 --- /dev/null +++ b/editor/icons/icon_delete_split.svg @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg4" + sodipodi:docname="icon_delete_split.svg" + inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="3066" + inkscape:window-height="1689" + id="namedview6" + showgrid="false" + inkscape:zoom="41.7193" + inkscape:cx="7.7924561" + inkscape:cy="6.0148972" + inkscape:window-x="134" + inkscape:window-y="55" + inkscape:window-maximized="1" + inkscape:current-layer="svg4" /> + <rect + style="fill:#800000" + id="rect12" + width="1.8456686" + height="2.0853658" + x="0.62321275" + y="6.9394455" /> + <rect + style="fill:#800000" + id="rect14" + width="1.6299411" + height="1.9894869" + x="12.488225" + y="7.1791425" /> + <rect + style="fill:#e9afaf" + id="rect37" + width="3.1640031" + height="0.40748528" + x="2.5407906" + y="7.9701433" /> + <rect + style="fill:#e9afaf" + id="rect39" + width="3.5235491" + height="0.52733386" + x="9.0126152" + y="8.0420523" /> + <rect + style="fill:#e9afaf" + id="rect41" + width="3.6433976" + height="0.4554247" + x="1.5110972" + y="-9.732645" + transform="rotate(123.99908)" /> + <rect + style="fill:#e9afaf" + id="rect41-3" + width="3.6433976" + height="0.4554247" + x="0.072069742" + y="-12.144793" + transform="rotate(123.99908)" /> +</svg> diff --git a/editor/icons/icon_enum.svg b/editor/icons/icon_enum.svg new file mode 100644 index 0000000000..e9c3fbbd2e --- /dev/null +++ b/editor/icons/icon_enum.svg @@ -0,0 +1,3 @@ +<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg"> +<path d="m3 2c-0.5304 8.01e-5 -1.0391 0.21085-1.4141 0.58594-0.37509 0.37501-0.58586 0.88366-0.58594 1.4141v1c-0.2652 4.01e-5 -0.51953 0.10542-0.70703 0.29297-0.18755 0.18751-0.29293 0.44183-0.29297 0.70703 4.0076e-5 0.2652 0.10542 0.51953 0.29297 0.70703 0.18751 0.18755 0.44183 0.29293 0.70703 0.29297v1c8.01e-5 0.5304 0.21085 1.0391 0.58594 1.4141 0.37501 0.37509 0.88366 0.58586 1.4141 0.58594h1v-2h-1v-4h1v-2zm3 0v8h4v-2h-2v-1h2v-2h-2v-1h2v-2zm6 0v2h1v4h-1v2h1c0.5304-8.03e-5 1.0391-0.21085 1.4141-0.58594 0.37509-0.37501 0.58586-0.88366 0.58594-1.4141v-1c0.2652-4.01e-5 0.51953-0.10542 0.70703-0.29297 0.18755-0.18751 0.29293-0.44183 0.29297-0.70703-4e-5 -0.2652-0.10542-0.51953-0.29297-0.70703-0.1875-0.18755-0.44183-0.29293-0.70703-0.29297v-1c-8e-5 -0.5304-0.21085-1.0391-0.58594-1.4141-0.37501-0.37509-0.88366-0.58586-1.4141-0.58594z" fill="#e0e0e0"/> +</svg> diff --git a/editor/icons/icon_help_search.svg b/editor/icons/icon_help_search.svg index c0768ea5ed..8e4f97d781 100644 --- a/editor/icons/icon_help_search.svg +++ b/editor/icons/icon_help_search.svg @@ -1,7 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)" stroke-width="2"> -<path transform="translate(0 1036.4)" d="m0 10v6h2c1.6569 0 3-1.3431 3-3s-1.3431-3-3-3zm5 3c0 1.6569 1.3431 3 3 3s3-1.3431 3-3-1.3431-3-3-3-3 1.3431-3 3zm6 0c0 1.6569 1.3431 3 3 3h1v-2h-1c-0.55228-1e-5 -0.99999-0.44772-1-1 1e-5 -0.55228 0.44772-0.99999 1-1h1v-2h-1c-1.6569 0-3 1.3431-3 3zm-9-1c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1zm6 0c0.55228 1e-5 0.99999 0.44772 1 1-9.6e-6 0.55228-0.44772 0.99999-1 1-0.55228-1e-5 -0.99999-0.44772-1-1 9.6e-6 -0.55228 0.44772-0.99999 1-1z" fill="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549"/> -<path d="m9 1036.4a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" fill="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549"/> -<path d="m7 1042.4-3 3" fill="none" stroke="#e0e0e0"/> +<g transform="translate(0 -1036.4)"> +<path transform="translate(0 1036.4)" d="m9 0a4 4 0 0 0 -4 4 4 4 0 0 0 0.55859 2.0273l-2.2656 2.2656 1.4141 1.4141 2.2656-2.2656a4 4 0 0 0 2.0273 0.55859 4 4 0 0 0 4 -4 4 4 0 0 0 -4 -4zm0 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm-9 8v6h2c1.6569 0 3-1.3431 3-3s-1.3431-3-3-3h-2zm5 3c0 1.6569 1.3431 3 3 3s3-1.3431 3-3-1.3431-3-3-3-3 1.3431-3 3zm6 0c0 1.6569 1.3431 3 3 3h1v-2h-1c-0.55228-1e-5 -0.99999-0.44772-1-1 1e-5 -0.55228 0.44772-0.99999 1-1h1v-2h-1c-1.6569 0-3 1.3431-3 3zm-9-1c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1v-2zm6 0c0.55228 1e-5 0.99999 0.44772 1 1-9.6e-6 0.55228-0.44772 0.99999-1 1-0.55228-1e-5 -0.99999-0.44772-1-1 9.6e-6 -0.55228 0.44772-0.99999 1-1z" fill="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549" stroke-width="2"/> </g> </svg> diff --git a/editor/icons/icon_key_selected.svg b/editor/icons/icon_key_selected.svg deleted file mode 100644 index c73d31981d..0000000000 --- a/editor/icons/icon_key_selected.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1044.4)"> -<rect transform="rotate(-45)" x="-741.53" y="741.08" width="6.1027" height="6.1027" ry=".76286" fill="#84c2ff"/> -</g> -</svg> diff --git a/editor/icons/icon_key_hover.svg b/editor/icons/icon_key_valid.svg index 4a3fab4754..4a3fab4754 100644 --- a/editor/icons/icon_key_hover.svg +++ b/editor/icons/icon_key_valid.svg diff --git a/editor/icons/icon_mesh.svg b/editor/icons/icon_mesh.svg index d90dc14b5b..f96efb0430 100644 --- a/editor/icons/icon_mesh.svg +++ b/editor/icons/icon_mesh.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2 -2 2 2 0 0 0 -1.0312 -1.75h0.03125v-6.5215a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm2.4141 3h5.8574a2 2 0 0 0 0.72852 0.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141l6.5859 6.5859h-5.8574a2 2 0 0 0 -0.72852 -0.73047v-5.8555z" fill="#ffd684"/> -</g> +<path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2 -2 2 2 0 0 0 -1.0312 -1.75h0.03125v-6.5215a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm2.4141 3h5.8574a2 2 0 0 0 0.72852 0.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141l6.5859 6.5859h-5.8574a2 2 0 0 0 -0.72852 -0.73047v-5.8555z" fill="#ffd684"/> </svg> diff --git a/editor/icons/icon_mesh_instance.svg b/editor/icons/icon_mesh_instance.svg index 3342a3e06d..2860cf6889 100644 --- a/editor/icons/icon_mesh_instance.svg +++ b/editor/icons/icon_mesh_instance.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2 -2 2 2 0 0 0 -1.0312 -1.75h0.03125v-6.5215a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm2.4141 3h5.8574a2 2 0 0 0 0.72852 0.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141l6.5859 6.5859h-5.8574a2 2 0 0 0 -0.72852 -0.73047v-5.8555z" fill="#fc9c9c" fill-opacity=".99608"/> -</g> +<path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2 -2 2 2 0 0 0 -1.0312 -1.75h0.03125v-6.5215a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm2.4141 3h5.8574a2 2 0 0 0 0.72852 0.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141l6.5859 6.5859h-5.8574a2 2 0 0 0 -0.72852 -0.73047v-5.8555z" fill="#fc9c9c" fill-opacity=".99608"/> </svg> diff --git a/editor/icons/icon_mesh_instance_2d.svg b/editor/icons/icon_mesh_instance_2d.svg new file mode 100644 index 0000000000..051547b524 --- /dev/null +++ b/editor/icons/icon_mesh_instance_2d.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h6.541a2 2 0 0 0 1.7285 1 2 2 0 0 0 2 -2 2 2 0 0 0 -1.0312 -1.75h0.03125v-6.5215a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm2.4141 3h5.8574a2 2 0 0 0 0.72852 0.73047v5.8555l-6.5859-6.5859zm-1.4141 1.4141l6.5859 6.5859h-5.8574a2 2 0 0 0 -0.72852 -0.73047v-5.8555z" fill="#a5b7f3"/> +</svg> diff --git a/editor/icons/icon_mesh_library.svg b/editor/icons/icon_mesh_library.svg index 3bef2df33c..3683650e2e 100644 --- a/editor/icons/icon_mesh_library.svg +++ b/editor/icons/icon_mesh_library.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h2.2695v-2h-2.2715a2 2 0 0 0 -0.72852 -0.73047v-5.8555l3 3v-0.41406a2.0002 2.0002 0 0 1 0.80859 -1.6055l-2.3945-2.3945h5.8574a2 2 0 0 0 0.72852 0.73047v1.2695a2.0002 2.0002 0 0 1 0.99805 0.27148 2.0002 2.0002 0 0 1 1.002 -0.27148v-1.2715a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm6 7v1 5 1h5c0.55228 0 1-0.4477 1-1v-5c0-0.5523-0.44772-1-1-1v4l-1-1-1 1v-4h-3z" fill="#ffd684"/> -</g> +<path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h2.2695v-2h-2.2715a2 2 0 0 0 -0.72852 -0.73047v-5.8555l3 3v-0.41406a2.0002 2.0002 0 0 1 0.80859 -1.6055l-2.3945-2.3945h5.8574a2 2 0 0 0 0.72852 0.73047v1.2695a2.0002 2.0002 0 0 1 0.99805 0.27148 2.0002 2.0002 0 0 1 1.002 -0.27148v-1.2715a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm6 7v1 5 1h5c0.55228 0 1-0.4477 1-1v-5c0-0.5523-0.44772-1-1-1v4l-1-1-1 1v-4h-3z" fill="#ffd684"/> </svg> diff --git a/editor/icons/icon_multi_mesh.svg b/editor/icons/icon_multi_mesh.svg index 2582ba9e51..522561bb28 100644 --- a/editor/icons/icon_multi_mesh.svg +++ b/editor/icons/icon_multi_mesh.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2 5.649e-4 0.71397 0.38169 1.3735 1 1.7305v6.541c-0.61771 0.35663-0.99874 1.0152-1 1.7285 0 1.1046 0.89543 2 2 2 0.71397-5.65e-4 1.3735-0.38169 1.7305-1h1.2695v-2h-1.2715c-0.17478-0.30301-0.42598-0.55488-0.72852-0.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c0.17532 0.30158 0.42647 0.55205 0.72852 0.72656v1.2734h2v-1.2695c0.61831-0.35698 0.99944-1.0165 1-1.7305 0-1.1046-0.89543-2-2-2-0.71397 5.648e-4 -1.3735 0.38169-1.7305 1h-6.541c-0.35663-0.61771-1.0152-0.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#ffd684"/> -</g> +<path d="m3 1c-1.1046 0-2 0.89543-2 2 5.649e-4 0.71397 0.38169 1.3735 1 1.7305v6.541c-0.61771 0.35663-0.99874 1.0152-1 1.7285 0 1.1046 0.89543 2 2 2 0.71397-5.65e-4 1.3735-0.38169 1.7305-1h1.2695v-2h-1.2715c-0.17478-0.30301-0.42598-0.55488-0.72852-0.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c0.17532 0.30158 0.42647 0.55205 0.72852 0.72656v1.2734h2v-1.2695c0.61831-0.35698 0.99944-1.0165 1-1.7305 0-1.1046-0.89543-2-2-2-0.71397 5.648e-4 -1.3735 0.38169-1.7305 1h-6.541c-0.35663-0.61771-1.0152-0.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#ffd684"/> </svg> diff --git a/editor/icons/icon_multi_mesh_instance.svg b/editor/icons/icon_multi_mesh_instance.svg index 0140f1137b..f873ac2bf3 100644 --- a/editor/icons/icon_multi_mesh_instance.svg +++ b/editor/icons/icon_multi_mesh_instance.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2 5.649e-4 0.71397 0.38169 1.3735 1 1.7305v6.541c-0.61771 0.35663-0.99874 1.0152-1 1.7285 0 1.1046 0.89543 2 2 2 0.71397-5.65e-4 1.3735-0.38169 1.7305-1h1.2695v-2h-1.2715c-0.17478-0.30301-0.42598-0.55488-0.72852-0.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c0.17532 0.30158 0.42647 0.55205 0.72852 0.72656v1.2734h2v-1.2695c0.61831-0.35698 0.99944-1.0165 1-1.7305 0-1.1046-0.89543-2-2-2-0.71397 5.648e-4 -1.3735 0.38169-1.7305 1h-6.541c-0.35663-0.61771-1.0152-0.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#fc9c9c" fill-opacity=".99608"/> -</g> +<path d="m3 1c-1.1046 0-2 0.89543-2 2 5.649e-4 0.71397 0.38169 1.3735 1 1.7305v6.541c-0.61771 0.35663-0.99874 1.0152-1 1.7285 0 1.1046 0.89543 2 2 2 0.71397-5.65e-4 1.3735-0.38169 1.7305-1h1.2695v-2h-1.2715c-0.17478-0.30301-0.42598-0.55488-0.72852-0.73047v-5.8555l3.5859 3.5859h1.4141v-1.4141l-3.5859-3.5859h5.8574c0.17532 0.30158 0.42647 0.55205 0.72852 0.72656v1.2734h2v-1.2695c0.61831-0.35698 0.99944-1.0165 1-1.7305 0-1.1046-0.89543-2-2-2-0.71397 5.648e-4 -1.3735 0.38169-1.7305 1h-6.541c-0.35663-0.61771-1.0152-0.99874-1.7285-1zm8 7v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#fc9c9c" fill-opacity=".99608"/> </svg> diff --git a/editor/icons/icon_navigation_mesh.svg b/editor/icons/icon_navigation_mesh.svg index cc04e06b51..831d1a0769 100644 --- a/editor/icons/icon_navigation_mesh.svg +++ b/editor/icons/icon_navigation_mesh.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h2.5078l0.75-2h-3.2598a2 2 0 0 0 -0.72852 -0.73047v-5.8555l4.6973 4.6973 0.77148-2.0566-4.0547-4.0547h5.8574a2 2 0 0 0 0.72852 0.73047v0.27148a2.0002 2.0002 0 0 1 0.023438 0 2.0002 2.0002 0 0 1 1.8496 1.2969l0.12695 0.33789v-1.9082a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm9 6l-3 8 3-2 3 2-3-8z" fill="#ffd684"/> -</g> +<path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h2.5078l0.75-2h-3.2598a2 2 0 0 0 -0.72852 -0.73047v-5.8555l4.6973 4.6973 0.77148-2.0566-4.0547-4.0547h5.8574a2 2 0 0 0 0.72852 0.73047v0.27148a2.0002 2.0002 0 0 1 0.023438 0 2.0002 2.0002 0 0 1 1.8496 1.2969l0.12695 0.33789v-1.9082a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm9 6l-3 8 3-2 3 2-3-8z" fill="#ffd684"/> </svg> diff --git a/editor/icons/icon_navigation_mesh_instance.svg b/editor/icons/icon_navigation_mesh_instance.svg index 85c6292290..e6636807af 100644 --- a/editor/icons/icon_navigation_mesh_instance.svg +++ b/editor/icons/icon_navigation_mesh_instance.svg @@ -1,7 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)" fill="#fc9c9c" fill-opacity=".99608"> -<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h2.5078l0.75-2h-3.2598a2 2 0 0 0 -0.72852 -0.73047v-5.8555l4.6973 4.6973 0.77148-2.0566-4.0547-4.0547h5.8574a2 2 0 0 0 0.72852 0.73047v0.27148a2.0002 2.0002 0 0 1 0.023438 0 2.0002 2.0002 0 0 1 1.8496 1.2969l0.12695 0.33789v-1.9082a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm9 6l-3 8 3-2 3 2-3-8z"/> -<rect x="12" y="1040.4" width="2" height="1"/> -<rect x="12" y="1040.4" width="2" height="1"/> -</g> +<path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305 -1h2.5078l0.75-2h-3.2598a2 2 0 0 0 -0.72852 -0.73047v-5.8555l4.6973 4.6973 0.77148-2.0566-4.0547-4.0547h5.8574a2 2 0 0 0 0.72852 0.73047v0.27148a2.0002 2.0002 0 0 1 0.023438 0 2.0002 2.0002 0 0 1 1.8496 1.2969l0.12695 0.33789v-1.9082a2 2 0 0 0 1 -1.7285 2 2 0 0 0 -2 -2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285 -1zm9 6l-3 8 3-2 3 2-3-8z" fill="#fc9c9c" fill-opacity=".99608"/> </svg> diff --git a/editor/icons/icon_plane_mesh.svg b/editor/icons/icon_plane_mesh.svg index 7a5c8f4354..dae7b02da5 100644 --- a/editor/icons/icon_plane_mesh.svg +++ b/editor/icons/icon_plane_mesh.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path d="m2 1048.4h12l-3-8h-6z" fill="none" stroke="#ffd684" stroke-linejoin="round" stroke-width="2"/> -</g> +<path d="m2 12h12l-3-8h-6z" fill="none" stroke="#ffd684" stroke-linejoin="round" stroke-width="2"/> </svg> diff --git a/editor/icons/icon_prism_mesh.svg b/editor/icons/icon_prism_mesh.svg index 68dfa117f7..8f8feb2eb6 100644 --- a/editor/icons/icon_prism_mesh.svg +++ b/editor/icons/icon_prism_mesh.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m7.9824 1.002a1.0001 1.0001 0 0 0 -0.81445 0.44336l-5.9727 8.9609-0.027344 0.039062a1 1 0 0 0 -0.0625 0.10742 1 1 0 0 0 0.44727 1.3418l6 3a1.0001 1.0001 0 0 0 0.89453 0l6-3a1 1 0 0 0 0.44726 -1.3418 1 1 0 0 0 -0.0625 -0.10742l-6-9a1.0001 1.0001 0 0 0 -0.84961 -0.44336zm-0.98242 4.3008v7.0801l-3.5391-1.7715 3.5391-5.3086zm2 0l3.5391 5.3086-3.5391 1.7715v-7.0801z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> -</g> +<path d="m7.9824 1.002a1.0001 1.0001 0 0 0 -0.81445 0.44336l-5.9727 8.9609-0.027344 0.03906a1 1 0 0 0 -0.0625 0.10742 1 1 0 0 0 0.44727 1.3418l6 3a1.0001 1.0001 0 0 0 0.89453 0l6-3a1 1 0 0 0 0.44726 -1.3418 1 1 0 0 0 -0.0625 -0.10742l-6-9a1.0001 1.0001 0 0 0 -0.84961 -0.44336zm-0.98242 4.3008v7.0801l-3.5391-1.7715zm2 0 3.5391 5.3086l-3.5391 1.7715z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> </svg> diff --git a/editor/icons/icon_quad_mesh.svg b/editor/icons/icon_quad_mesh.svg index bf7b593e9e..40a07b36f7 100644 --- a/editor/icons/icon_quad_mesh.svg +++ b/editor/icons/icon_quad_mesh.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path d="m15 1037.4v14h-14v-14zm-2 2h-8.5859l8.5859 8.5859zm-10 1.4141v8.5859h8.5859z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> -</g> +<path d="m15 1v14h-14v-14zm-2 2h-8.5859l8.5859 8.5859zm-10 1.4141v8.5859h8.5859z" fill="#ffd684"/> </svg> diff --git a/editor/icons/icon_rayito.svg b/editor/icons/icon_rayito.svg index e1891e783a..937a5cc4d7 100644 --- a/editor/icons/icon_rayito.svg +++ b/editor/icons/icon_rayito.svg @@ -1,6 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)" fill="#ffd684"> -<rect transform="matrix(1 0 -.14142 .98995 0 0)" x="152.19" y="1047.9" width="7" height="7.0711"/> -<path d="m6 1043.4h8l-9 8z"/> +<g transform="translate(0 -1036.4)"> +<path transform="translate(0 1036.4)" d="m4 1l-1 7h2.875l-0.875 7 9-8h-3.8574l0.85742-6h-7z" fill="#ffd684"/> </g> </svg> diff --git a/editor/icons/icon_reflection_probe.svg b/editor/icons/icon_reflection_probe.svg index 0a7f537737..e0f1572317 100644 --- a/editor/icons/icon_reflection_probe.svg +++ b/editor/icons/icon_reflection_probe.svg @@ -1,7 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)" fill="none" stroke="#fc9c9c" stroke-linejoin="round" stroke-opacity=".99608" stroke-width="2"> -<path d="m2 1045.4v5h12v-4"/> -<path d="m2 1040.4 5 6 7-7"/> -<path d="m14 1043.4v-4h-4" stroke-linecap="round"/> +<g transform="translate(0 -1036.4)"> +<path transform="translate(0 1036.4)" d="m10 2a1.0001 1.0001 0 1 0 0 2h1.5859l-4.5195 4.5195-4.2988-5.1582-1.5352 1.2793 5 6a1.0001 1.0001 0 0 0 1.4746 0.064453l5.293-5.293v1.5879a1.0001 1.0001 0 1 0 2 0v-4a1.0001 1.0001 0 0 0 -1 -1h-4zm-9 7v5a1.0001 1.0001 0 0 0 1 1h12a1.0001 1.0001 0 0 0 1 -1v-4h-2v3h-10v-4h-2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fc9c9c" fill-opacity=".99608" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> </g> </svg> diff --git a/editor/icons/icon_short_cut.svg b/editor/icons/icon_short_cut.svg index 736f1f3c02..8c7978e522 100644 --- a/editor/icons/icon_short_cut.svg +++ b/editor/icons/icon_short_cut.svg @@ -1,6 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)" fill-opacity=".99608"> -<path transform="translate(0 1036.4)" d="m4 2c-0.55228 0-1 0.4477-1 1v9.084c4.015e-4 0.506 0.448 0.91602 1 0.91602h8c0.552 0 0.9996-0.41002 1-0.91602v-9.084c0-0.5523-0.44772-1-1-1h-8zm-3 2v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-1v9a0.99998 0.99998 0 0 1 -1 1h-10a1 1 0 0 1 -1 -1v-9h-1zm6 0h3l-1 3h2l-4 4 1-3h-2l1-4z" fill="#e0e0e0"/> -<rect x="27" y="1038.4" width="7" height="14" fill="#fff"/> +<g transform="translate(0 -1036.4)"> +<path transform="translate(0 1036.4)" d="m4 2c-0.55228 0-1 0.4477-1 1v9.084c4.015e-4 0.506 0.448 0.91602 1 0.91602h8c0.552 0 0.9996-0.41002 1-0.91602v-9.084c0-0.5523-0.44772-1-1-1h-8zm-3 2v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-9h-1v9a0.99998 0.99998 0 0 1 -1 1h-10a1 1 0 0 1 -1 -1v-9h-1zm6 0h3l-1 3h2l-4 4 1-3h-2l1-4z" fill="#e0e0e0" fill-opacity=".99608"/> </g> </svg> diff --git a/editor/icons/icon_skeleton.svg b/editor/icons/icon_skeleton.svg index d5c5f301bb..ef563338c8 100644 --- a/editor/icons/icon_skeleton.svg +++ b/editor/icons/icon_skeleton.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.4531v3.5469a2 2 0 0 0 1 1.7324 2 2 0 0 0 1 0.26562v0.001953h4v-0.001953a2 2 0 0 0 1 -0.26562 2 2 0 0 0 1 -1.7324v-3.5469a4 4 0 0 0 2 -3.4531 4 4 0 0 0 -4 -4h-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-4 2h2v1h-2v-1zm-2 2h1v1h1v-1h1 1v1h1v-1h1v0.86719 3.1328h-1v-1h-1v1h-1-1v-1h-1v1h-1v-3.1309-0.86914z" fill="#fc9c9c" fill-opacity=".99608"/> -</g> +<path d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.4531v3.5469a2 2 0 0 0 1 1.7324 2 2 0 0 0 1 0.26562v0.001953h4v-0.001953a2 2 0 0 0 1 -0.26562 2 2 0 0 0 1 -1.7324v-3.5469a4 4 0 0 0 2 -3.4531 4 4 0 0 0 -4 -4h-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-4 2h2v1h-2v-1zm-2 2h1v1h1v-1h1 1v1h1v-1h1v0.86719 3.1328h-1v-1h-1v1h-1-1v-1h-1v1h-1v-3.1309-0.86914z" fill="#fc9c9c" fill-opacity=".99608"/> </svg> diff --git a/editor/icons/icon_skeleton_2d.svg b/editor/icons/icon_skeleton_2d.svg new file mode 100644 index 0000000000..1ee9bde2a6 --- /dev/null +++ b/editor/icons/icon_skeleton_2d.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m6 2a4 4 0 0 0 -4 4 4 4 0 0 0 2 3.4531v3.5469a2 2 0 0 0 1 1.7324 2 2 0 0 0 1 0.26562v0.001953h4v-0.001953a2 2 0 0 0 1 -0.26562 2 2 0 0 0 1 -1.7324v-3.5469a4 4 0 0 0 2 -3.4531 4 4 0 0 0 -4 -4h-4zm-1 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-4 2h2v1h-2v-1zm-2 2h1v1h1v-1h1 1v1h1v-1h1v0.86719 3.1328h-1v-1h-1v1h-1-1v-1h-1v1h-1v-3.1309-0.86914z" fill="#a5b7f3"/> +</svg> diff --git a/editor/icons/icon_sphere_mesh.svg b/editor/icons/icon_sphere_mesh.svg index 519b69cbd7..e298bbef3d 100644 --- a/editor/icons/icon_sphere_mesh.svg +++ b/editor/icons/icon_sphere_mesh.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m8 1c-3.8541 0-7 3.1459-7 7 0 3.8542 3.1459 7 7 7 3.8541 0 7-3.1458 7-7 0-3.8541-3.1459-7-7-7zm-1 2.0977v4.8711c-1.2931-0.071342-2.6061-0.29819-3.9434-0.69141 0.30081-2.0978 1.8852-3.7665 3.9434-4.1797zm2 0c2.0549 0.41253 3.637 2.0767 3.9414 4.1699-1.3046 0.36677-2.6158 0.60259-3.9414 0.6875v-4.8574zm3.7852 6.2812c-0.50864 1.7788-1.9499 3.1531-3.7852 3.5215v-2.9512c1.2792-0.072301 2.5419-0.26704 3.7852-0.57031zm-9.5645 0.017578c1.2733 0.31892 2.5337 0.50215 3.7793 0.5625v2.9414c-1.8291-0.36719-3.266-1.7339-3.7793-3.5039z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> -</g> +<path d="m8 1c-3.8541 0-7 3.1459-7 7 0 3.8542 3.1459 7 7 7 3.8541 0 7-3.1458 7-7 0-3.8541-3.1459-7-7-7zm-1 2.0977v4.8711c-1.2931-0.071342-2.6061-0.29819-3.9434-0.69141 0.30081-2.0978 1.8852-3.7665 3.9434-4.1797zm2 0c2.0549 0.41253 3.637 2.0767 3.9414 4.1699-1.3046 0.36677-2.6158 0.60259-3.9414 0.6875v-4.8574zm3.7852 6.2812c-0.50864 1.7788-1.9499 3.1531-3.7852 3.5215v-2.9512c1.2792-0.072301 2.5419-0.26704 3.7852-0.57031zm-9.5645 0.017578c1.2733 0.31892 2.5337 0.50215 3.7793 0.5625v2.9414c-1.8291-0.36719-3.266-1.7339-3.7793-3.5039z" fill="#ffd684"/> </svg> diff --git a/editor/icons/icon_timer.svg b/editor/icons/icon_timer.svg index e5907cea20..6bf4a29158 100644 --- a/editor/icons/icon_timer.svg +++ b/editor/icons/icon_timer.svg @@ -1,8 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(0 -1036.4)"> -<rect x="2" y="1037.4" width="12" height="2" ry="1" fill="#e0e0e0"/> -<rect x="2" y="1049.4" width="12" height="2" ry="1" fill="#e0e0e0"/> -<path d="m3 1050.4h10l-3-6h-4z" fill="#e0e0e0"/> -<path d="m3 1038.4h10c0 2-3 4-4 6 1 2 4 4 4 6h-10c0-2 3-4 4-6-1-2-4-4-4-6z" fill="none" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="2"/> +<path transform="translate(0 1036.4)" d="m3 1a1.0001 1.0001 0 0 0 -0.38672 0.078125 1.0001 1.0001 0 0 0 -0.0019531 0c-0.0022762 9.545e-4 -0.0035918 0.0029354-0.0058593 0.0039062a1.0001 1.0001 0 0 0 -0.31055 0.20898c-0.0012857 0.0012787-0.0026276 0.0026206-0.0039063 0.0039063a1.0001 1.0001 0 0 0 -0.20508 0.30469c-0.0029915 0.0068502-0.0069239 0.012601-0.0097656 0.019531a1.0001 1.0001 0 0 0 -0.076172 0.38086c0 1.5 0.96697 2.6247 1.873 3.6602 0.76081 0.8695 1.4161 1.6425 1.875 2.3398-0.45889 0.6974-1.1141 1.4723-1.875 2.3418-0.90608 1.0355-1.873 2.1582-1.873 3.6582a1.0001 1.0001 0 0 0 0.078125 0.38867v0.001953c9.292e-4 0.002204 0.0029617 0.003663 0.0039062 0.005859a1.0001 1.0001 0 0 0 0.20898 0.30664c0.0010185 0.001027 0.0028834 0.004836 0.0039063 0.005859a1.0001 1.0001 0 0 0 0.30078 0.20312c0.0093182 0.004119 0.017877 0.007879 0.027344 0.011719a1.0001 1.0001 0 0 0 0.37695 0.076172h10a1.0001 1.0001 0 0 0 0.375 -0.074219c0.010174-0.0041 0.019294-0.009251 0.029297-0.013672a1.0001 1.0001 0 0 0 0.29297 -0.19922c0.004786-0.004679 0.00898-0.008899 0.013672-0.013672a1.0001 1.0001 0 0 0 0.20117 -0.29492c0.004119-0.009318 0.007879-0.017877 0.011719-0.027344a1.0001 1.0001 0 0 0 0.076172 -0.37695c0-1.5-0.96697-2.6227-1.873-3.6582-0.76087-0.8695-1.4161-1.6444-1.875-2.3418 0.4589-0.6973 1.1142-1.4703 1.875-2.3398 0.90608-1.0355 1.873-2.1602 1.873-3.6602a1.0001 1.0001 0 0 0 -0.078125 -0.39062 1.0001 1.0001 0 0 0 -0.21484 -0.31641 1.0001 1.0001 0 0 0 -0.31055 -0.21094 1.0001 1.0001 0 0 0 -0.011718 -0.0058593 1.0001 1.0001 0 0 0 -0.38477 -0.076172h-10zm1.5879 2h6.8242c-0.2378 0.4408-0.3055 0.7892-0.78906 1.3418-0.84392 0.9645-1.8983 1.9723-2.5176 3.2109a1.0001 1.0001 0 0 0 -0.10547 0.44727 1.0001 1.0001 0 0 0 -0.10547 -0.44727c-0.61926-1.2386-1.6737-2.2464-2.5176-3.2109-0.48356-0.5526-0.55126-0.901-0.78906-1.3418z" fill="#e0e0e0"/> </g> </svg> diff --git a/editor/icons/icon_tree.svg b/editor/icons/icon_tree.svg index 62efb9f94f..15be220451 100644 --- a/editor/icons/icon_tree.svg +++ b/editor/icons/icon_tree.svg @@ -1,6 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(0 -1036.4)"> -<rect x="29" y="1042.4" width="1" height="1" fill="#fefeff"/> <path transform="translate(0 1036.4)" d="m1 1v13c5.52e-5 0.55226 0.44774 0.99994 1 1h13v-2h-12v-6h2v3c5.52e-5 0.55226 0.44774 0.99994 1 1h9v-2h-8v-2h8v-2h-12v-2h12v-2z" fill="#a5efac"/> </g> </svg> diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 863b13cbd7..c1e897a04c 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -480,7 +480,7 @@ Error ColladaImport::_create_material(const String &p_target) { } } - float roughness = Math::sqrt(1.0 - ((Math::log(effect.shininess) / Math::log(2.0)) / 8.0)); //not very right.. + float roughness = (effect.shininess - 1.0) / 510; material->set_roughness(roughness); if (effect.double_sided) { diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 2636839764..af79f9946a 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -762,14 +762,22 @@ PoolVector<Color> EditorSceneImporterGLTF::_decode_accessor_as_color(GLTFState & PoolVector<Color> ret; if (attribs.size() == 0) return ret; - ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret); + int type = state.accessors[p_accessor].type; + ERR_FAIL_COND_V(!(type == TYPE_VEC3 || type == TYPE_VEC4), ret); + int components; + if (type == TYPE_VEC3) { + components = 3; + } else { // TYPE_VEC4 + components = 4; + } + ERR_FAIL_COND_V(attribs.size() % components != 0, ret); const double *attribs_ptr = attribs.ptr(); - int ret_size = attribs.size() / 4; + int ret_size = attribs.size() / components; ret.resize(ret_size); { PoolVector<Color>::Write w = ret.write(); for (int i = 0; i < ret_size; i++) { - w[i] = Color(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], attribs_ptr[i * 4 + 3]); + w[i] = Color(attribs_ptr[i * 4 + 0], attribs_ptr[i * 4 + 1], attribs_ptr[i * 4 + 2], components == 4 ? attribs_ptr[i * 4 + 3] : 1.0); } } return ret; @@ -1724,14 +1732,19 @@ void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vecto for (int i = 0; i < n->joints.size(); i++) { ERR_FAIL_COND(n->joints[i].skin < 0); - int bone_index = skeletons[n->joints[i].skin]->get_bone_count(); - skeletons[n->joints[i].skin]->add_bone(n->name); + int bone_index = n->joints[i].bone; + + Skeleton *s = skeletons[n->joints[i].skin]; + while (s->get_bone_count() <= bone_index) { + s->add_bone("Bone " + itos(s->get_bone_count())); + } + if (p_parent_bones.size()) { - skeletons[n->joints[i].skin]->set_bone_parent(bone_index, p_parent_bones[i]); + s->set_bone_parent(bone_index, p_parent_bones[i]); } - skeletons[n->joints[i].skin]->set_bone_rest(bone_index, state.skins[n->joints[i].skin].bones[n->joints[i].bone].inverse_bind.affine_inverse()); + s->set_bone_rest(bone_index, state.skins[n->joints[i].skin].bones[n->joints[i].bone].inverse_bind.affine_inverse()); - n->godot_nodes.push_back(skeletons[n->joints[i].skin]); + n->godot_nodes.push_back(s); n->joints[i].godot_bone_index = bone_index; parent_bones.push_back(bone_index); } @@ -1875,6 +1888,8 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye animation.instance(); animation->set_name(name); + float length = 0; + for (Map<int, GLTFAnimation::Track>::Element *E = anim.tracks.front(); E; E = E->next()) { const GLTFAnimation::Track &track = E->get(); @@ -1893,8 +1908,6 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye node_path = ap->get_parent()->get_path_to(node->godot_nodes[i]); } - float length = 0; - for (int i = 0; i < track.rotation_track.times.size(); i++) { length = MAX(length, track.rotation_track.times[i]); } @@ -1911,8 +1924,6 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye } } - animation->set_length(length); - if (track.rotation_track.values.size() || track.translation_track.values.size() || track.scale_track.values.size()) { //make transform track int track_idx = animation->get_track_count(); @@ -2030,6 +2041,7 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye } } } + animation->set_length(length); ap->add_animation(name, animation); } diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp index 22c32f5fc9..ec0500361d 100644 --- a/editor/import/resource_importer_csv_translation.cpp +++ b/editor/import/resource_importer_csv_translation.cpp @@ -50,7 +50,7 @@ void ResourceImporterCSVTranslation::get_recognized_extensions(List<String> *p_e } String ResourceImporterCSVTranslation::get_save_extension() const { - return ""; //does not save a single resoure + return ""; //does not save a single resource } String ResourceImporterCSVTranslation::get_resource_type() const { diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index c22e1cd88b..7612f18aff 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -1011,6 +1011,7 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) { player->seek_delta(pos, pos - cpos); } else { + player->stop(true); player->seek(pos, true); } @@ -1678,10 +1679,10 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay onion_skinning->get_popup()->add_separator(); onion_skinning->get_popup()->add_item(TTR("Depth"), -1); onion_skinning->get_popup()->set_item_disabled(onion_skinning->get_popup()->get_item_count() - 1, true); - onion_skinning->get_popup()->add_check_item(TTR("1 step"), ONION_SKINNING_1_STEP); + onion_skinning->get_popup()->add_radio_check_item(TTR("1 step"), ONION_SKINNING_1_STEP); onion_skinning->get_popup()->set_item_checked(onion_skinning->get_popup()->get_item_count() - 1, true); - onion_skinning->get_popup()->add_check_item(TTR("2 steps"), ONION_SKINNING_2_STEPS); - onion_skinning->get_popup()->add_check_item(TTR("3 steps"), ONION_SKINNING_3_STEPS); + onion_skinning->get_popup()->add_radio_check_item(TTR("2 steps"), ONION_SKINNING_2_STEPS); + onion_skinning->get_popup()->add_radio_check_item(TTR("3 steps"), ONION_SKINNING_3_STEPS); onion_skinning->get_popup()->add_separator(); onion_skinning->get_popup()->add_check_item(TTR("Differences Only"), ONION_SKINNING_DIFFERENCES_ONLY); onion_skinning->get_popup()->add_check_item(TTR("Force White Modulate"), ONION_SKINNING_FORCE_WHITE_MODULATE); diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index f0e186e4b0..37213c1866 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -756,6 +756,7 @@ void AnimationTreeEditor::_gui_input(Ref<InputEvent> p_event) { if (rclick_type == CLICK_INPUT_SLOT || rclick_type == CLICK_OUTPUT_SLOT) { node_popup->clear(); + node_popup->set_size(Size2(1, 1)); node_popup->add_item(TTR("Disconnect"), NODE_DISCONNECT); if (anim_tree->node_get_type(rclick_node) == AnimationTreePlayer::NODE_TRANSITION) { node_popup->add_item(TTR("Add Input"), NODE_ADD_INPUT); @@ -774,6 +775,7 @@ void AnimationTreeEditor::_gui_input(Ref<InputEvent> p_event) { if (rclick_type == CLICK_NODE) { node_popup->clear(); + node_popup->set_size(Size2(1, 1)); node_popup->add_item(TTR("Rename"), NODE_RENAME); node_popup->add_item(TTR("Remove"), NODE_ERASE); if (anim_tree->node_get_type(rclick_node) == AnimationTreePlayer::NODE_TRANSITION) diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 26afc78825..c203b4b81e 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -30,11 +30,10 @@ #include "asset_library_editor_plugin.h" +#include "core/io/json.h" +#include "core/version.h" #include "editor_node.h" #include "editor_settings.h" -#include "io/json.h" - -#include "version_generated.gen.h" void EditorAssetLibraryItem::configure(const String &p_title, int p_asset_id, const String &p_category, int p_category_id, const String &p_author, int p_author_id, int p_rating, const String &p_cost) { @@ -515,6 +514,7 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() { download = memnew(HTTPRequest); add_child(download); download->connect("request_completed", this, "_http_download_completed"); + download->set_use_threads(EDITOR_DEF("asset_library/use_threads", true)); download_error = memnew(AcceptDialog); add_child(download_error); @@ -534,11 +534,9 @@ void EditorAssetLibrary::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { - TextureRect *tf = memnew(TextureRect); - tf->set_texture(get_icon("Error", "EditorIcons")); + error_tr->set_texture(get_icon("Error", "EditorIcons")); reverse->set_icon(get_icon("Sort", "EditorIcons")); - error_hb->add_child(tf); error_label->raise(); } break; @@ -586,6 +584,8 @@ void EditorAssetLibrary::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { library_scroll_bg->add_style_override("panel", get_stylebox("bg", "Tree")); + error_tr->set_texture(get_icon("Error", "EditorIcons")); + reverse->set_icon(get_icon("Sort", "EditorIcons")); } break; } } @@ -833,6 +833,7 @@ void EditorAssetLibrary::_request_image(ObjectID p_for, String p_image_url, Imag iq.image_index = p_image_index; iq.image_type = p_type; iq.request = memnew(HTTPRequest); + iq.request->set_use_threads(EDITOR_DEF("asset_library/use_threads", true)); iq.target = p_for; iq.queue_id = ++last_queue_id; @@ -877,7 +878,8 @@ void EditorAssetLibrary::_search(int p_page) { } args += String() + "sort=" + sort_key[sort->get_selected()]; - args += "&godot_version=" + itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR); + // We use the "branch" version, i.e. major.minor, as patch releases should be compatible + args += "&godot_version=" + String(VERSION_BRANCH); String support_list; for (int i = 0; i < SUPPORT_MAX; i++) { @@ -1452,6 +1454,8 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { error_label = memnew(Label); error_label->add_color_override("color", get_color("error_color", "Editor")); error_hb->add_child(error_label); + error_tr = memnew(TextureRect); + error_hb->add_child(error_tr); description = NULL; diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h index b344716c1d..89b79d7cfb 100644 --- a/editor/plugins/asset_library_editor_plugin.h +++ b/editor/plugins/asset_library_editor_plugin.h @@ -194,6 +194,7 @@ class EditorAssetLibrary : public PanelContainer { Button *search; ProgressBar *load_status; HBoxContainer *error_hb; + TextureRect *error_tr; Label *error_label; MenuButton *support; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 9680ad07e7..b8d0958c99 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -210,6 +210,7 @@ void CanvasItemEditor::_snap_other_nodes(Point2 p_value, Point2 &r_current_snap, Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const CanvasItem *p_canvas_item, unsigned int p_forced_modes) { bool snapped[2] = { false, false }; + bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); // Smart snap using the canvas position Vector2 output = p_target; @@ -219,7 +220,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const rotation = p_canvas_item->get_global_transform_with_canvas().get_rotation(); // Parent sides and center - if ((snap_active && snap_node_parent && (p_modes & SNAP_NODE_PARENT)) || (p_forced_modes & SNAP_NODE_PARENT)) { + if ((is_snap_active && snap_node_parent && (p_modes & SNAP_NODE_PARENT)) || (p_forced_modes & SNAP_NODE_PARENT)) { Point2 begin; Point2 end; bool can_snap = false; @@ -241,7 +242,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const } // Self anchors - if ((snap_active && snap_node_anchors && (p_modes & SNAP_NODE_ANCHORS)) || (p_forced_modes & SNAP_NODE_ANCHORS)) { + if ((is_snap_active && snap_node_anchors && (p_modes & SNAP_NODE_ANCHORS)) || (p_forced_modes & SNAP_NODE_ANCHORS)) { if (const Control *c = Object::cast_to<Control>(p_canvas_item)) { Point2 begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_LEFT), c->get_anchor(MARGIN_TOP)))); Point2 end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_RIGHT), c->get_anchor(MARGIN_BOTTOM)))); @@ -251,7 +252,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const } // Self sides - if ((snap_active && snap_node_sides && (p_modes & SNAP_NODE_SIDES)) || (p_forced_modes & SNAP_NODE_SIDES)) { + if ((is_snap_active && snap_node_sides && (p_modes & SNAP_NODE_SIDES)) || (p_forced_modes & SNAP_NODE_SIDES)) { Point2 begin = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position()); Point2 end = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position() + p_canvas_item->_edit_get_rect().get_size()); _snap_if_closer_point(p_target, begin, output, snapped, rotation); @@ -259,18 +260,18 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const } // Self center - if ((snap_active && snap_node_center && (p_modes & SNAP_NODE_CENTER)) || (p_forced_modes & SNAP_NODE_CENTER)) { + if ((is_snap_active && snap_node_center && (p_modes & SNAP_NODE_CENTER)) || (p_forced_modes & SNAP_NODE_CENTER)) { Point2 center = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position() + p_canvas_item->_edit_get_rect().get_size() / 2.0); _snap_if_closer_point(p_target, center, output, snapped, rotation); } } // Other nodes sides - if ((snap_active && snap_other_nodes && (p_modes & SNAP_OTHER_NODES)) || (p_forced_modes & SNAP_OTHER_NODES)) { + if ((is_snap_active && snap_other_nodes && (p_modes & SNAP_OTHER_NODES)) || (p_forced_modes & SNAP_OTHER_NODES)) { _snap_other_nodes(p_target, output, snapped, get_tree()->get_edited_scene_root(), p_canvas_item); } - if (((snap_active && snap_guides && (p_modes & SNAP_GUIDES)) || (p_forced_modes & SNAP_GUIDES)) && fmod(rotation, (real_t)360.0) == 0.0) { + if (((is_snap_active && snap_guides && (p_modes & SNAP_GUIDES)) || (p_forced_modes & SNAP_GUIDES)) && fmod(rotation, (real_t)360.0) == 0.0) { // Guides if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) { Array vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_"); @@ -287,7 +288,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const } } - if (((snap_active && snap_grid && (p_modes & SNAP_GRID)) || (p_forced_modes & SNAP_GRID)) && fmod(rotation, (real_t)360.0) == 0.0) { + if (((is_snap_active && snap_grid && (p_modes & SNAP_GRID)) || (p_forced_modes & SNAP_GRID)) && fmod(rotation, (real_t)360.0) == 0.0) { // Grid Point2 offset = grid_offset; if (snap_relative) { @@ -313,7 +314,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const } float CanvasItemEditor::snap_angle(float p_target, float p_start) const { - return (snap_rotation && snap_rotation_step != 0) ? Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset : p_target; + return (((snap_active || snap_rotation) ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) ? Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset : p_target; } void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) { @@ -597,7 +598,7 @@ void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items bone = Object::cast_to<Node2D>(bone->get_parent()); } - //Save the bone state and lenght if we have an IK chain + //Save the bone state and length if we have an IK chain if (ik_found) { bone = Object::cast_to<Node2D>(canvas_item); Transform2D bone_xform = bone->get_global_transform(); @@ -676,12 +677,12 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve Ref<InputEventMouseButton> b = p_event; Ref<InputEventMouseMotion> m = p_event; - // Start draging a guide + // Start dragging a guide if (drag_type == DRAG_NONE) { if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed()) { if (show_guides && show_rulers && EditorNode::get_singleton()->get_edited_scene()) { Transform2D xform = viewport_scrollable->get_transform() * transform; - // Retreive the guide lists + // Retrieve the guide lists Array vguides; if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) { vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_"); @@ -855,8 +856,8 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { if (b->get_button_index() == BUTTON_WHEEL_DOWN) { // Scroll or pan down if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) { - v_scroll->set_value(v_scroll->get_value() + int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor()); - _update_scroll(0); + view_offset.y += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); + _update_scrollbars(); viewport->update(); } else { _zoom_on_position(zoom * (1 - (0.05 * b->get_factor())), b->get_position()); @@ -867,8 +868,8 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { if (b->get_button_index() == BUTTON_WHEEL_UP) { // Scroll or pan up if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) { - v_scroll->set_value(v_scroll->get_value() - int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor()); - _update_scroll(0); + view_offset.y -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); + _update_scrollbars(); viewport->update(); } else { _zoom_on_position(zoom * ((0.95 + (0.05 * b->get_factor())) / 0.95), b->get_position()); @@ -879,7 +880,9 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { if (b->get_button_index() == BUTTON_WHEEL_LEFT) { // Pan left if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) { - h_scroll->set_value(h_scroll->get_value() - int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor()); + view_offset.x -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); + _update_scrollbars(); + viewport->update(); return true; } } @@ -887,7 +890,9 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { if (b->get_button_index() == BUTTON_WHEEL_RIGHT) { // Pan right if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) { - h_scroll->set_value(h_scroll->get_value() + int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor()); + view_offset.x += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor(); + _update_scrollbars(); + viewport->update(); return true; } } @@ -907,9 +912,10 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { } else { relative = m->get_relative(); } - - h_scroll->set_value(h_scroll->get_value() - relative.x / zoom); - v_scroll->set_value(v_scroll->get_value() - relative.y / zoom); + view_offset.x -= relative.x / zoom; + view_offset.y -= relative.y / zoom; + _update_scrollbars(); + viewport->update(); return true; } } @@ -926,8 +932,10 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) { if (pan_gesture.is_valid()) { // Pan gesture const Vector2 delta = (int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom) * pan_gesture->get_delta(); - h_scroll->set_value(h_scroll->get_value() + delta.x); - v_scroll->set_value(v_scroll->get_value() + delta.y); + view_offset.x += delta.x; + view_offset.y += delta.y; + _update_scrollbars(); + viewport->update(); return true; } @@ -1227,26 +1235,26 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) { switch (drag_type) { case DRAG_ANCHOR_TOP_LEFT: - if (!use_single_axis || (use_single_axis && !use_y)) control->set_anchor(MARGIN_LEFT, new_anchor.x, false, false); - if (!use_single_axis || (use_single_axis && use_y)) control->set_anchor(MARGIN_TOP, new_anchor.y, false, false); + if (!use_single_axis || !use_y) control->set_anchor(MARGIN_LEFT, new_anchor.x, false, false); + if (!use_single_axis || use_y) control->set_anchor(MARGIN_TOP, new_anchor.y, false, false); break; case DRAG_ANCHOR_TOP_RIGHT: - if (!use_single_axis || (use_single_axis && !use_y)) control->set_anchor(MARGIN_RIGHT, new_anchor.x, false, false); - if (!use_single_axis || (use_single_axis && use_y)) control->set_anchor(MARGIN_TOP, new_anchor.y, false, false); + if (!use_single_axis || !use_y) control->set_anchor(MARGIN_RIGHT, new_anchor.x, false, false); + if (!use_single_axis || use_y) control->set_anchor(MARGIN_TOP, new_anchor.y, false, false); break; case DRAG_ANCHOR_BOTTOM_RIGHT: - if (!use_single_axis || (use_single_axis && !use_y)) control->set_anchor(MARGIN_RIGHT, new_anchor.x, false, false); - if (!use_single_axis || (use_single_axis && use_y)) control->set_anchor(MARGIN_BOTTOM, new_anchor.y, false, false); + if (!use_single_axis || !use_y) control->set_anchor(MARGIN_RIGHT, new_anchor.x, false, false); + if (!use_single_axis || use_y) control->set_anchor(MARGIN_BOTTOM, new_anchor.y, false, false); break; case DRAG_ANCHOR_BOTTOM_LEFT: - if (!use_single_axis || (use_single_axis && !use_y)) control->set_anchor(MARGIN_LEFT, new_anchor.x, false, false); - if (!use_single_axis || (use_single_axis && use_y)) control->set_anchor(MARGIN_BOTTOM, new_anchor.y, false, false); + if (!use_single_axis || !use_y) control->set_anchor(MARGIN_LEFT, new_anchor.x, false, false); + if (!use_single_axis || use_y) control->set_anchor(MARGIN_BOTTOM, new_anchor.y, false, false); break; case DRAG_ANCHOR_ALL: - if (!use_single_axis || (use_single_axis && !use_y)) control->set_anchor(MARGIN_LEFT, new_anchor.x, false, true); - if (!use_single_axis || (use_single_axis && !use_y)) control->set_anchor(MARGIN_RIGHT, new_anchor.x, false, true); - if (!use_single_axis || (use_single_axis && use_y)) control->set_anchor(MARGIN_TOP, new_anchor.y, false, true); - if (!use_single_axis || (use_single_axis && use_y)) control->set_anchor(MARGIN_BOTTOM, new_anchor.y, false, true); + if (!use_single_axis || !use_y) control->set_anchor(MARGIN_LEFT, new_anchor.x, false, true); + if (!use_single_axis || !use_y) control->set_anchor(MARGIN_RIGHT, new_anchor.x, false, true); + if (!use_single_axis || use_y) control->set_anchor(MARGIN_TOP, new_anchor.y, false, true); + if (!use_single_axis || use_y) control->set_anchor(MARGIN_BOTTOM, new_anchor.y, false, true); break; default: break; @@ -1615,10 +1623,10 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { if (drag_type == DRAG_NONE) { if (b.is_valid() && - ((b->get_button_index() == BUTTON_LEFT && b->get_alt() && tool == TOOL_SELECT) || + ((b->get_button_index() == BUTTON_RIGHT && b->get_alt() && tool == TOOL_SELECT) || (b->get_button_index() == BUTTON_LEFT && tool == TOOL_LIST_SELECT))) { // Popup the selection menu list - Point2 click = transform.xform(b->get_position()); + Point2 click = transform.affine_inverse().xform(b->get_position()); Node *scene = editor->get_edited_scene(); @@ -1664,8 +1672,6 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { selection_menu_additive_selection = b->get_shift(); selection_menu->set_global_position(b->get_global_position()); selection_menu->popup(); - selection_menu->call_deferred("grab_click_focus"); - selection_menu->set_invalidate_click_until_motion(); return true; } } @@ -1681,7 +1687,22 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { // Find the item to select CanvasItem *canvas_item = NULL; Vector<_SelectResult> selection; - _find_canvas_items_at_pos(click, scene, selection, 1); + _find_canvas_items_at_pos(click, scene, selection, editor_selection->get_selection().empty() ? 1 : 0); + + for (int i = 0; i < selection.size(); i++) { + if (editor_selection->is_selected(selection[i].item)) { + // Drag the node(s) if requested + List<CanvasItem *> selection = _get_edited_canvas_items(); + + drag_type = DRAG_ALL; + drag_selection = selection; + drag_from = click; + _save_canvas_item_state(drag_selection); + + return true; + } + } + if (!selection.empty()) canvas_item = selection[0].item; @@ -1952,10 +1973,11 @@ void CanvasItemEditor::_draw_rulers() { Color font_color = get_color("font_color", "Editor"); font_color.a = 0.8; Ref<Font> font = get_font("rulers", "EditorFonts"); + bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); // The rule transform Transform2D ruler_transform = Transform2D(); - if (show_grid || (snap_active && snap_grid)) { + if (show_grid || (is_snap_active && snap_grid)) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (snap_relative && selection.size() > 0) { ruler_transform.translate(_get_encompassing_rect_from_list(selection).position); @@ -2384,26 +2406,34 @@ void CanvasItemEditor::_draw_straight_line(Point2 p_from, Point2 p_to, Color p_c } void CanvasItemEditor::_draw_axis() { - RID ci = viewport->get_canvas_item(); - Color x_axis_color(1.0, 0.4, 0.4, 0.6); - Color y_axis_color(0.4, 1.0, 0.4, 0.6); - Color area_axis_color(0.4, 0.4, 1.0, 0.4); + if (show_origin) { - _draw_straight_line(Point2(), Point2(1, 0), x_axis_color); - _draw_straight_line(Point2(), Point2(0, 1), y_axis_color); + Color x_axis_color(1.0, 0.4, 0.4, 0.6); + Color y_axis_color(0.4, 1.0, 0.4, 0.6); - Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); + _draw_straight_line(Point2(), Point2(1, 0), x_axis_color); + _draw_straight_line(Point2(), Point2(0, 1), y_axis_color); + } - Vector2 screen_endpoints[4] = { - transform.xform(Vector2(0, 0)), - transform.xform(Vector2(screen_size.width, 0)), - transform.xform(Vector2(screen_size.width, screen_size.height)), - transform.xform(Vector2(0, screen_size.height)) - }; + if (show_viewport) { - for (int i = 0; i < 4; i++) { - VisualServer::get_singleton()->canvas_item_add_line(ci, screen_endpoints[i], screen_endpoints[(i + 1) % 4], area_axis_color); + RID ci = viewport->get_canvas_item(); + + Color area_axis_color(0.4, 0.4, 1.0, 0.4); + + Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); + + Vector2 screen_endpoints[4] = { + transform.xform(Vector2(0, 0)), + transform.xform(Vector2(screen_size.width, 0)), + transform.xform(Vector2(screen_size.width, screen_size.height)), + transform.xform(Vector2(0, screen_size.height)) + }; + + for (int i = 0; i < 4; i++) { + VisualServer::get_singleton()->canvas_item_add_line(ci, screen_endpoints[i], screen_endpoints[(i + 1) % 4], area_axis_color); + } } } @@ -2529,6 +2559,11 @@ void CanvasItemEditor::_build_bones_list(Node *p_node) { } void CanvasItemEditor::_draw_viewport() { + // Update the transform + transform = Transform2D(); + transform.scale_basis(Size2(zoom, zoom)); + transform.elements[2] = -view_offset * zoom; + editor->get_scene_root()->set_global_canvas_transform(transform); // hide/show buttons depending on the selection bool all_locked = true; @@ -2559,8 +2594,6 @@ void CanvasItemEditor::_draw_viewport() { group_button->set_disabled(selection.empty()); ungroup_button->set_visible(all_group); - _update_scrollbars(); - _draw_grid(); _draw_selection(); _draw_axis(); @@ -2761,17 +2794,18 @@ void CanvasItemEditor::edit(CanvasItem *p_canvas_item) { // Clear the selection editor_selection->clear(); //_clear_canvas_items(); editor_selection->add_node(p_canvas_item); - viewport->update(); } void CanvasItemEditor::_update_scrollbars() { updating_scroll = true; + // Move the zoom buttons Point2 zoom_hb_begin = Point2(5, 5); zoom_hb_begin += (show_rulers) ? Point2(RULER_WIDTH, RULER_WIDTH) : Point2(); zoom_hb->set_begin(zoom_hb_begin); + // Move and resize the scrollbars Size2 size = viewport->get_size(); Size2 hmin = h_scroll->get_minimum_size(); Size2 vmin = v_scroll->get_minimum_size(); @@ -2782,8 +2816,8 @@ void CanvasItemEditor::_update_scrollbars() { h_scroll->set_begin(Point2((show_rulers) ? RULER_WIDTH : 0, size.height - hmin.height)); h_scroll->set_end(Point2(size.width - vmin.width, size.height)); + // Get the visible frame Size2 screen_rect = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); - Rect2 local_rect = Rect2(Point2(), viewport->get_size() - Size2(vmin.width, hmin.height)); bone_last_frame++; @@ -2813,48 +2847,56 @@ void CanvasItemEditor::_update_scrollbars() { canvas_item_rect.size += screen_rect * 2; canvas_item_rect.position -= screen_rect; - Point2 ofs; + // Constraints the view offset and updates the scrollbars + Point2 begin = canvas_item_rect.position; + Point2 end = canvas_item_rect.position + canvas_item_rect.size - local_rect.size / zoom; if (canvas_item_rect.size.height <= (local_rect.size.y / zoom)) { + if (ABS(begin.y - previous_update_view_offset.y) < ABS(begin.y - view_offset.y)) { + view_offset.y = previous_update_view_offset.y; + } + v_scroll->hide(); - ofs.y = canvas_item_rect.position.y; } else { - - v_scroll->show(); - v_scroll->set_min(canvas_item_rect.position.y); - v_scroll->set_max(canvas_item_rect.position.y + canvas_item_rect.size.y); - v_scroll->set_page(local_rect.size.y / zoom); - if (first_update) { - //so 0,0 is visible - v_scroll->set_value(-10); - h_scroll->set_value(-10); - first_update = false; + if (view_offset.y > end.y && view_offset.y > previous_update_view_offset.y) { + view_offset.y = MAX(end.y, previous_update_view_offset.y); + } + if (view_offset.y < begin.y && view_offset.y < previous_update_view_offset.y) { + view_offset.y = MIN(begin.y, previous_update_view_offset.y); } - ofs.y = v_scroll->get_value(); + v_scroll->show(); + v_scroll->set_min(MIN(view_offset.y, begin.y)); + v_scroll->set_max(MAX(view_offset.y, end.y) + screen_rect.y); + v_scroll->set_page(screen_rect.y); } if (canvas_item_rect.size.width <= (local_rect.size.x / zoom)) { + if (ABS(begin.x - previous_update_view_offset.x) < ABS(begin.x - view_offset.x)) { + view_offset.x = previous_update_view_offset.x; + } h_scroll->hide(); - ofs.x = canvas_item_rect.position.x; } else { + if (view_offset.x > end.x && view_offset.x > previous_update_view_offset.x) { + view_offset.x = MAX(end.x, previous_update_view_offset.x); + } + if (view_offset.x < begin.x && view_offset.x < previous_update_view_offset.x) { + view_offset.x = MIN(begin.x, previous_update_view_offset.x); + } h_scroll->show(); - h_scroll->set_min(canvas_item_rect.position.x); - h_scroll->set_max(canvas_item_rect.position.x + canvas_item_rect.size.x); - h_scroll->set_page(local_rect.size.x / zoom); - ofs.x = h_scroll->get_value(); + h_scroll->set_min(MIN(view_offset.x, begin.x)); + h_scroll->set_max(MAX(view_offset.x, end.x) + screen_rect.x); + h_scroll->set_page(screen_rect.x); } - //transform=Matrix32(); - transform.elements[2] = -ofs * zoom; - - editor->get_scene_root()->set_global_canvas_transform(transform); + // Calculate scrollable area + v_scroll->set_value(view_offset.y); + h_scroll->set_value(view_offset.x); + previous_update_view_offset = view_offset; updating_scroll = false; - - //transform.scale_basis(Vector2(zoom,zoom)); } void CanvasItemEditor::_update_scroll(float) { @@ -2862,19 +2904,8 @@ void CanvasItemEditor::_update_scroll(float) { if (updating_scroll) return; - Point2 ofs; - ofs.x = h_scroll->get_value(); - ofs.y = v_scroll->get_value(); - - //current_window->set_scroll(-ofs); - - transform = Transform2D(); - - transform.scale_basis(Size2(zoom, zoom)); - transform.elements[2] = -ofs; - - editor->get_scene_root()->set_global_canvas_transform(transform); - + view_offset.x = h_scroll->get_value(); + view_offset.y = v_scroll->get_value(); viewport->update(); } @@ -2941,10 +2972,10 @@ void CanvasItemEditor::_zoom_on_position(float p_zoom, Point2 p_position) { zoom = p_zoom; Point2 ofs = p_position; ofs = ofs / prev_zoom - ofs / zoom; - h_scroll->set_value(Math::round(h_scroll->get_value() + ofs.x)); - v_scroll->set_value(Math::round(v_scroll->get_value() + ofs.y)); + view_offset.x = Math::round(view_offset.x + ofs.x); + view_offset.y = Math::round(view_offset.y + ofs.y); - _update_scroll(0); + _update_scrollbars(); viewport->update(); } @@ -2987,6 +3018,18 @@ void CanvasItemEditor::_popup_callback(int p_op) { view_menu->get_popup()->set_item_checked(idx, show_grid); viewport->update(); } break; + case SHOW_ORIGIN: { + show_origin = !show_origin; + int idx = view_menu->get_popup()->get_item_index(SHOW_ORIGIN); + view_menu->get_popup()->set_item_checked(idx, show_origin); + viewport->update(); + } break; + case SHOW_VIEWPORT: { + show_viewport = !show_viewport; + int idx = view_menu->get_popup()->get_item_index(SHOW_VIEWPORT); + view_menu->get_popup()->set_item_checked(idx, show_viewport); + viewport->update(); + } break; case SNAP_USE_NODE_PARENT: { snap_node_parent = !snap_node_parent; int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_PARENT); @@ -3517,8 +3560,10 @@ void CanvasItemEditor::_focus_selection(int p_op) { center = rect.position + rect.size / 2; Vector2 offset = viewport->get_size() / 2 - editor->get_scene_root()->get_global_canvas_transform().xform(center); - h_scroll->set_value(h_scroll->get_value() - offset.x / zoom); - v_scroll->set_value(v_scroll->get_value() - offset.y / zoom); + view_offset.x -= offset.x / zoom; + view_offset.y -= offset.y / zoom; + _update_scrollbars(); + viewport->update(); } else { // VIEW_FRAME_TO_SELECTION @@ -3527,7 +3572,7 @@ void CanvasItemEditor::_focus_selection(int p_op) { float scale_y = viewport->get_size().y / rect.size.y; zoom = scale_x < scale_y ? scale_x : scale_y; zoom *= 0.90; - _update_scroll(0); + viewport->update(); call_deferred("_popup_callback", VIEW_CENTER_TO_SELECTION); } } @@ -3540,6 +3585,7 @@ void CanvasItemEditor::_bind_methods() { ClassDB::bind_method("_button_zoom_plus", &CanvasItemEditor::_button_zoom_plus); ClassDB::bind_method("_button_toggle_snap", &CanvasItemEditor::_button_toggle_snap); ClassDB::bind_method("_update_scroll", &CanvasItemEditor::_update_scroll); + ClassDB::bind_method("_update_scrollbars", &CanvasItemEditor::_update_scrollbars); ClassDB::bind_method("_popup_callback", &CanvasItemEditor::_popup_callback); ClassDB::bind_method("_get_editor_data", &CanvasItemEditor::_get_editor_data); ClassDB::bind_method("_button_tool_select", &CanvasItemEditor::_button_tool_select); @@ -3560,7 +3606,7 @@ Dictionary CanvasItemEditor::get_state() const { Dictionary state; state["zoom"] = zoom; - state["ofs"] = Point2(h_scroll->get_value(), v_scroll->get_value()); + state["ofs"] = view_offset; state["grid_offset"] = grid_offset; state["grid_step"] = grid_step; state["snap_rotation_offset"] = snap_rotation_offset; @@ -3574,6 +3620,8 @@ Dictionary CanvasItemEditor::get_state() const { state["snap_grid"] = snap_grid; state["snap_guides"] = snap_guides; state["show_grid"] = show_grid; + state["show_origin"] = show_origin; + state["show_viewport"] = show_viewport; state["show_rulers"] = show_rulers; state["show_guides"] = show_guides; state["show_helpers"] = show_helpers; @@ -3592,10 +3640,9 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { } if (state.has("ofs")) { - _update_scrollbars(); // i wonder how safe is calling this here.. - Point2 ofs = p_state["ofs"]; - h_scroll->set_value(ofs.x); - v_scroll->set_value(ofs.y); + view_offset = p_state["ofs"]; + previous_update_view_offset = view_offset; + _update_scrollbars(); } if (state.has("grid_offset")) { @@ -3667,6 +3714,18 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { view_menu->get_popup()->set_item_checked(idx, show_grid); } + if (state.has("show_origin")) { + show_origin = state["show_origin"]; + int idx = view_menu->get_popup()->get_item_index(SHOW_ORIGIN); + view_menu->get_popup()->set_item_checked(idx, show_origin); + } + + if (state.has("show_viewport")) { + show_viewport = state["show_viewport"]; + int idx = view_menu->get_popup()->get_item_index(SHOW_VIEWPORT); + view_menu->get_popup()->set_item_checked(idx, show_viewport); + } + if (state.has("show_rulers")) { show_rulers = state["show_rulers"]; int idx = view_menu->get_popup()->get_item_index(SHOW_RULERS); @@ -3763,6 +3822,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { viewport_scrollable->set_clip_contents(true); viewport_scrollable->set_v_size_flags(SIZE_EXPAND_FILL); viewport_scrollable->set_h_size_flags(SIZE_EXPAND_FILL); + viewport_scrollable->connect("draw", this, "_update_scrollbars"); ViewportContainer *scene_tree = memnew(ViewportContainer); viewport_scrollable->add_child(scene_tree); @@ -3781,12 +3841,12 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { h_scroll = memnew(HScrollBar); viewport->add_child(h_scroll); - h_scroll->connect("value_changed", this, "_update_scroll", Vector<Variant>(), Object::CONNECT_DEFERRED); + h_scroll->connect("value_changed", this, "_update_scroll"); h_scroll->hide(); v_scroll = memnew(VScrollBar); viewport->add_child(v_scroll); - v_scroll->connect("value_changed", this, "_update_scroll", Vector<Variant>(), Object::CONNECT_DEFERRED); + v_scroll->connect("value_changed", this, "_update_scroll"); v_scroll->hide(); zoom_hb = memnew(HBoxContainer); @@ -3809,7 +3869,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { zoom_plus->set_focus_mode(FOCUS_NONE); updating_scroll = false; - first_update = true; select_button = memnew(ToolButton); hb->add_child(select_button); @@ -3940,6 +3999,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_helpers", TTR("Show Helpers"), KEY_H), SHOW_HELPERS); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_rulers", TTR("Show Rulers"), KEY_R), SHOW_RULERS); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_guides", TTR("Show Guides"), KEY_Y), SHOW_GUIDES); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_origin", TTR("Show Origin")), SHOW_ORIGIN); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_viewport", TTR("Show Viewport")), SHOW_VIEWPORT); p->add_separator(); p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTR("Center Selection"), KEY_F), VIEW_CENTER_TO_SELECTION); p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KEY_MASK_SHIFT | KEY_F), VIEW_FRAME_TO_SELECTION); @@ -4025,10 +4086,14 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { key_scale = false; show_grid = false; + show_origin = true; + show_viewport = true; show_helpers = false; show_rulers = true; show_guides = true; zoom = 1; + view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH); + previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen grid_offset = Point2(); grid_step = Point2(10, 10); grid_step_multiplier = 0; diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index adf203cf3d..da7ce9172a 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -100,6 +100,8 @@ class CanvasItemEditor : public VBoxContainer { SHOW_HELPERS, SHOW_RULERS, SHOW_GUIDES, + SHOW_ORIGIN, + SHOW_VIEWPORT, LOCK_SELECTED, UNLOCK_SELECTED, GROUP_SELECTED, @@ -199,7 +201,6 @@ class CanvasItemEditor : public VBoxContainer { bool selection_menu_additive_selection; Tool tool; - bool first_update; Control *viewport; Control *viewport_scrollable; @@ -215,8 +216,12 @@ class CanvasItemEditor : public VBoxContainer { bool show_grid; bool show_rulers; bool show_guides; + bool show_origin; + bool show_viewport; bool show_helpers; float zoom; + Point2 view_offset; + Point2 previous_update_view_offset; Point2 grid_offset; Point2 grid_step; diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp index d8d3c0cee6..4410242d9c 100644 --- a/editor/plugins/collision_polygon_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_editor_plugin.cpp @@ -140,7 +140,7 @@ bool CollisionPolygonEditor::forward_spatial_gui_input(Camera *p_camera, const R Vector<Vector2> poly = node->get_polygon(); //first check if a point is to be added (segment split) - real_t grab_treshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8); + real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8); switch (mode) { @@ -159,7 +159,7 @@ bool CollisionPolygonEditor::forward_spatial_gui_input(Camera *p_camera, const R return true; } else { - if (wip.size() > 1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x, wip[0].y, depth))).distance_to(gpoint) < grab_treshold) { + if (wip.size() > 1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x, wip[0].y, depth))).distance_to(gpoint) < grab_threshold) { //wip closed _wip_close(); @@ -213,7 +213,7 @@ bool CollisionPolygonEditor::forward_spatial_gui_input(Camera *p_camera, const R continue; //not valid to reuse point real_t d = cp.distance_to(gpoint); - if (d < closest_dist && d < grab_treshold) { + if (d < closest_dist && d < grab_threshold) { closest_dist = d; closest_pos = cp; closest_idx = i; @@ -242,7 +242,7 @@ bool CollisionPolygonEditor::forward_spatial_gui_input(Camera *p_camera, const R Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth))); real_t d = cp.distance_to(gpoint); - if (d < closest_dist && d < grab_treshold) { + if (d < closest_dist && d < grab_threshold) { closest_dist = d; closest_pos = cp; closest_idx = i; @@ -288,7 +288,7 @@ bool CollisionPolygonEditor::forward_spatial_gui_input(Camera *p_camera, const R Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth))); real_t d = cp.distance_to(gpoint); - if (d < closest_dist && d < grab_treshold) { + if (d < closest_dist && d < grab_threshold) { closest_dist = d; closest_pos = cp; closest_idx = i; diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 47d730cdf1..8542296bde 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -40,7 +40,7 @@ #include "scene/resources/material.h" #include "scene/resources/mesh.h" -static void post_process_preview(Ref<Image> p_image) { +void post_process_preview(Ref<Image> p_image) { if (p_image->get_format() != Image::FORMAT_RGBA8) p_image->convert(Image::FORMAT_RGBA8); diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index 2e12515e30..35b5c3a5f0 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -33,6 +33,8 @@ #include "editor/editor_resource_preview.h" +void post_process_preview(Ref<Image> p_image); + class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator { GDCLASS(EditorTexturePreviewPlugin, EditorResourcePreviewGenerator) public: diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp index fd5a1f185f..8b44f672b0 100644 --- a/editor/plugins/item_list_editor_plugin.cpp +++ b/editor/plugins/item_list_editor_plugin.cpp @@ -42,9 +42,18 @@ bool ItemListPlugin::_set(const StringName &p_name, const Variant &p_value) { set_item_text(idx, p_value); else if (what == "icon") set_item_icon(idx, p_value); - else if (what == "checkable") - set_item_checkable(idx, p_value); - else if (what == "checked") + else if (what == "checkable") { + // This keeps compatibility to/from versions where this property was a boolean, before radio buttons + switch ((int)p_value) { + case 0: + case 1: + set_item_checkable(idx, p_value); + break; + case 2: + set_item_radio_checkable(idx, true); + break; + } + } else if (what == "checked") set_item_checked(idx, p_value); else if (what == "id") set_item_id(idx, p_value); @@ -68,9 +77,14 @@ bool ItemListPlugin::_get(const StringName &p_name, Variant &r_ret) const { r_ret = get_item_text(idx); else if (what == "icon") r_ret = get_item_icon(idx); - else if (what == "checkable") - r_ret = is_item_checkable(idx); - else if (what == "checked") + else if (what == "checkable") { + // This keeps compatibility to/from versions where this property was a boolean, before radio buttons + if (!is_item_checkable(idx)) { + r_ret = 0; + } else { + r_ret = is_item_radio_checkable(idx) ? 2 : 1; + } + } else if (what == "checked") r_ret = is_item_checked(idx); else if (what == "id") r_ret = get_item_id(idx); @@ -95,7 +109,7 @@ void ItemListPlugin::_get_property_list(List<PropertyInfo> *p_list) const { int flags = get_flags(); if (flags & FLAG_CHECKABLE) { - p_list->push_back(PropertyInfo(Variant::BOOL, base + "checkable")); + p_list->push_back(PropertyInfo(Variant::BOOL, base + "checkable", PROPERTY_HINT_ENUM, "No,As checkbox,As radio button")); p_list->push_back(PropertyInfo(Variant::BOOL, base + "checked")); } @@ -247,7 +261,7 @@ void ItemListEditor::_node_removed(Node *p_node) { void ItemListEditor::_notification(int p_notification) { - if (p_notification == NOTIFICATION_ENTER_TREE) { + if (p_notification == NOTIFICATION_ENTER_TREE || p_notification == NOTIFICATION_THEME_CHANGED) { add_button->set_icon(get_icon("Add", "EditorIcons")); del_button->set_icon(get_icon("Remove", "EditorIcons")); diff --git a/editor/plugins/item_list_editor_plugin.h b/editor/plugins/item_list_editor_plugin.h index bd7d3db10d..d6a071b9b9 100644 --- a/editor/plugins/item_list_editor_plugin.h +++ b/editor/plugins/item_list_editor_plugin.h @@ -74,7 +74,9 @@ public: virtual Ref<Texture> get_item_icon(int p_idx) const { return Ref<Texture>(); }; virtual void set_item_checkable(int p_idx, bool p_check) {} + virtual void set_item_radio_checkable(int p_idx, bool p_check) {} virtual bool is_item_checkable(int p_idx) const { return false; }; + virtual bool is_item_radio_checkable(int p_idx) const { return false; }; virtual void set_item_checked(int p_idx, bool p_checked) {} virtual bool is_item_checked(int p_idx) const { return false; }; @@ -145,7 +147,9 @@ public: virtual Ref<Texture> get_item_icon(int p_idx) const { return pp->get_item_icon(p_idx); } virtual void set_item_checkable(int p_idx, bool p_check) { pp->set_item_as_checkable(p_idx, p_check); } + virtual void set_item_radio_checkable(int p_idx, bool p_check) { pp->set_item_as_radio_checkable(p_idx, p_check); } virtual bool is_item_checkable(int p_idx) const { return pp->is_item_checkable(p_idx); } + virtual bool is_item_radio_checkable(int p_idx) const { return pp->is_item_radio_checkable(p_idx); } virtual void set_item_checked(int p_idx, bool p_checked) { pp->set_item_checked(p_idx, p_checked); } virtual bool is_item_checked(int p_idx) const { return pp->is_item_checked(p_idx); } diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp index cb5f7ba76c..7ea2b27744 100644 --- a/editor/plugins/mesh_instance_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_editor_plugin.cpp @@ -344,6 +344,10 @@ void MeshInstanceEditor::_create_outline_mesh() { err_dialog->set_text(TTR("Mesh has not surface to create outlines from!")); err_dialog->popup_centered_minsize(); return; + } else if (mesh->get_surface_count() == 1 && mesh->surface_get_primitive_type(0) != Mesh::PRIMITIVE_TRIANGLES) { + err_dialog->set_text(TTR("Mesh primitive type is not PRIMITIVE_TRIANGLES!")); + err_dialog->popup_centered_minsize(); + return; } Ref<Mesh> mesho = mesh->create_outline(outline_size->get_value()); diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 1db6621718..3a169bd780 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -59,10 +59,13 @@ void Polygon2DEditor::_notification(int p_what) { button_uv->set_icon(get_icon("Uv", "EditorIcons")); + uv_button[UV_MODE_CREATE]->set_icon(get_icon("Add", "EditorIcons")); uv_button[UV_MODE_EDIT_POINT]->set_icon(get_icon("ToolSelect", "EditorIcons")); uv_button[UV_MODE_MOVE]->set_icon(get_icon("ToolMove", "EditorIcons")); uv_button[UV_MODE_ROTATE]->set_icon(get_icon("ToolRotate", "EditorIcons")); uv_button[UV_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons")); + uv_button[UV_MODE_ADD_SPLIT]->set_icon(get_icon("AddSplit", "EditorIcons")); + uv_button[UV_MODE_REMOVE_SPLIT]->set_icon(get_icon("DeleteSplit", "EditorIcons")); b_snap_grid->set_icon(get_icon("Grid", "EditorIcons")); b_snap_enable->set_icon(get_icon("SnapGrid", "EditorIcons")); @@ -75,6 +78,36 @@ void Polygon2DEditor::_notification(int p_what) { } } +void Polygon2DEditor::_uv_edit_mode_select(int p_mode) { + + if (p_mode == 0) { + uv_button[UV_MODE_CREATE]->hide(); + for (int i = UV_MODE_MOVE; i <= UV_MODE_SCALE; i++) { + uv_button[i]->show(); + } + uv_button[UV_MODE_ADD_SPLIT]->hide(); + uv_button[UV_MODE_REMOVE_SPLIT]->hide(); + _uv_mode(UV_MODE_EDIT_POINT); + + } else if (p_mode == 1) { + for (int i = 0; i <= UV_MODE_SCALE; i++) { + uv_button[i]->show(); + } + uv_button[UV_MODE_ADD_SPLIT]->hide(); + uv_button[UV_MODE_REMOVE_SPLIT]->hide(); + _uv_mode(UV_MODE_EDIT_POINT); + } else { + for (int i = 0; i <= UV_MODE_SCALE; i++) { + uv_button[i]->hide(); + } + uv_button[UV_MODE_ADD_SPLIT]->show(); + uv_button[UV_MODE_REMOVE_SPLIT]->show(); + _uv_mode(UV_MODE_ADD_SPLIT); + } + + uv_edit_draw->update(); +} + void Polygon2DEditor::_menu_option(int p_option) { switch (p_option) { @@ -180,6 +213,10 @@ void Polygon2DEditor::_set_snap_step_y(float p_val) { void Polygon2DEditor::_uv_mode(int p_mode) { + split_create = false; + uv_drag = false; + uv_create = false; + uv_mode = UVMode(p_mode); for (int i = 0; i < UV_MODE_MAX; i++) { uv_button[i]->set_pressed(p_mode == i); @@ -203,7 +240,56 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { uv_drag_from = Vector2(mb->get_position().x, mb->get_position().y); uv_drag = true; uv_prev = node->get_uv(); + + if (uv_edit_mode[0]->is_pressed()) { //edit uv + uv_prev = node->get_uv(); + } else { //edit polygon + uv_prev = node->get_polygon(); + } + uv_move_current = uv_mode; + if (uv_move_current == UV_MODE_CREATE) { + + if (!uv_create) { + uv_prev.resize(0); + Vector2 tuv = mtx.affine_inverse().xform(Vector2(mb->get_position().x, mb->get_position().y)); + uv_prev.push_back(tuv); + uv_create_to = tuv; + uv_drag_index = 0; + uv_drag_from = tuv; + uv_drag = true; + uv_create = true; + uv_create_uv_prev = node->get_uv(); + uv_create_poly_prev = node->get_polygon(); + splits_prev = node->get_splits(); + node->set_polygon(uv_prev); + node->set_uv(uv_prev); + + } else { + Vector2 tuv = mtx.affine_inverse().xform(Vector2(mb->get_position().x, mb->get_position().y)); + + if (uv_prev.size() > 3 && tuv.distance_to(uv_prev[0]) < 8) { + undo_redo->create_action(TTR("Create Polygon & UV")); + undo_redo->add_do_method(node, "set_uv", node->get_uv()); + undo_redo->add_undo_method(node, "set_uv", uv_prev); + undo_redo->add_do_method(node, "set_polygon", node->get_polygon()); + undo_redo->add_undo_method(node, "set_polygon", uv_prev); + undo_redo->add_do_method(uv_edit_draw, "update"); + undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->commit_action(); + uv_drag = false; + uv_create = false; + _uv_mode(UV_MODE_EDIT_POINT); + } else { + uv_prev.push_back(tuv); + uv_drag_index = uv_prev.size() - 1; + uv_drag_from = tuv; + } + node->set_polygon(uv_prev); + node->set_uv(uv_prev); + } + } + if (uv_move_current == UV_MODE_EDIT_POINT) { if (mb->get_shift() && mb->get_command()) @@ -230,11 +316,120 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { uv_drag = false; } } - } else if (uv_drag) { + + if (uv_move_current == UV_MODE_ADD_SPLIT) { + + int drag_index = -1; + drag_index = -1; + for (int i = 0; i < uv_prev.size(); i++) { + + Vector2 tuv = mtx.xform(uv_prev[i]); + if (tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y)) < 8) { + drag_index = i; + } + } + + if (drag_index == -1) { + split_create = false; + return; + } + + if (split_create) { + + split_create = false; + if (drag_index < uv_drag_index) { + SWAP(drag_index, uv_drag_index); + } + bool valid = true; + if (drag_index == uv_drag_index) { + valid = false; + } + if (drag_index + 1 == uv_drag_index) { + //not a split,goes along the edge + valid = false; + } + if (drag_index == uv_prev.size() - 1 && uv_drag_index == 0) { + //not a split,goes along the edge + valid = false; + } + for (int i = 0; i < splits_prev.size(); i += 2) { + if (splits_prev[i] == uv_drag_index && splits_prev[i + 1] == drag_index) { + //already exists + valid = false; + } + if (splits_prev[i] > uv_drag_index && splits_prev[i + 1] > drag_index) { + //crossing + valid = false; + } + + if (splits_prev[i] < uv_drag_index && splits_prev[i + 1] < drag_index) { + //crossing opposite direction + valid = false; + } + } + + if (valid) { + + splits_prev.push_back(uv_drag_index); + splits_prev.push_back(drag_index); + + undo_redo->create_action(TTR("Add Split")); + + undo_redo->add_do_method(node, "set_splits", splits_prev); + undo_redo->add_undo_method(node, "set_splits", node->get_splits()); + undo_redo->add_do_method(uv_edit_draw, "update"); + undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->commit_action(); + } else { + error->set_text(TTR("Invalid Split")); + error->popup_centered_minsize(); + } + + } else { + uv_drag_index = drag_index; + split_create = true; + uv_create_to = mtx.affine_inverse().xform(Vector2(mb->get_position().x, mb->get_position().y)); + } + } + + if (uv_move_current == UV_MODE_REMOVE_SPLIT) { + + for (int i = 0; i < splits_prev.size(); i += 2) { + if (splits_prev[i] < 0 || splits_prev[i] >= uv_prev.size()) + continue; + if (splits_prev[i + 1] < 0 || splits_prev[i] >= uv_prev.size()) + continue; + Vector2 e[2] = { mtx.xform(uv_prev[splits_prev[i]]), mtx.xform(uv_prev[splits_prev[i + 1]]) }; + Vector2 mp = Vector2(mb->get_position().x, mb->get_position().y); + Vector2 cp = Geometry::get_closest_point_to_segment_2d(mp, e); + if (cp.distance_to(mp) < 8) { + splits_prev.remove(i); + splits_prev.remove(i); + + undo_redo->create_action(TTR("Remove Split")); + + undo_redo->add_do_method(node, "set_splits", splits_prev); + undo_redo->add_undo_method(node, "set_splits", node->get_splits()); + undo_redo->add_do_method(uv_edit_draw, "update"); + undo_redo->add_undo_method(uv_edit_draw, "update"); + undo_redo->commit_action(); + + break; + } + } + } + + } else if (uv_drag && !uv_create) { undo_redo->create_action(TTR("Transform UV Map")); - undo_redo->add_do_method(node, "set_uv", node->get_uv()); - undo_redo->add_undo_method(node, "set_uv", uv_prev); + + if (uv_edit_mode[0]->is_pressed()) { //edit uv + undo_redo->add_do_method(node, "set_uv", node->get_uv()); + undo_redo->add_undo_method(node, "set_uv", uv_prev); + } else if (uv_edit_mode[1]->is_pressed()) { //edit polygon + undo_redo->add_do_method(node, "set_polygon", node->get_polygon()); + undo_redo->add_undo_method(node, "set_polygon", uv_prev); + } undo_redo->add_do_method(uv_edit_draw, "update"); undo_redo->add_undo_method(uv_edit_draw, "update"); undo_redo->commit_action(); @@ -244,10 +439,25 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) { - if (uv_drag) { + if (uv_create) { uv_drag = false; - node->set_uv(uv_prev); + uv_create = false; + node->set_uv(uv_create_uv_prev); + node->set_polygon(uv_create_poly_prev); + node->set_splits(splits_prev); + uv_edit_draw->update(); + } else if (uv_drag) { + + uv_drag = false; + if (uv_edit_mode[0]->is_pressed()) { //edit uv + node->set_uv(uv_prev); + } else if (uv_edit_mode[1]->is_pressed()) { //edit polygon + node->set_polygon(uv_prev); + } + uv_edit_draw->update(); + } else if (split_create) { + split_create = false; uv_edit_draw->update(); } @@ -277,11 +487,21 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { switch (uv_move_current) { + case UV_MODE_CREATE: { + if (uv_create) { + uv_create_to = mtx.affine_inverse().xform(Vector2(mm->get_position().x, mm->get_position().y)); + } + } break; case UV_MODE_EDIT_POINT: { PoolVector<Vector2> uv_new = uv_prev; uv_new.set(uv_drag_index, uv_new[uv_drag_index] + drag); - node->set_uv(uv_new); + + if (uv_edit_mode[0]->is_pressed()) { //edit uv + node->set_uv(uv_new); + } else if (uv_edit_mode[1]->is_pressed()) { //edit polygon + node->set_polygon(uv_new); + } } break; case UV_MODE_MOVE: { @@ -289,7 +509,11 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { for (int i = 0; i < uv_new.size(); i++) uv_new.set(i, uv_new[i] + drag); - node->set_uv(uv_new); + if (uv_edit_mode[0]->is_pressed()) { //edit uv + node->set_uv(uv_new); + } else if (uv_edit_mode[1]->is_pressed()) { //edit polygon + node->set_polygon(uv_new); + } } break; case UV_MODE_ROTATE: { @@ -309,7 +533,11 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { uv_new.set(i, center + rel); } - node->set_uv(uv_new); + if (uv_edit_mode[0]->is_pressed()) { //edit uv + node->set_uv(uv_new); + } else if (uv_edit_mode[1]->is_pressed()) { //edit polygon + node->set_polygon(uv_new); + } } break; case UV_MODE_SCALE: { @@ -334,10 +562,17 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { uv_new.set(i, center + rel); } - node->set_uv(uv_new); + if (uv_edit_mode[0]->is_pressed()) { //edit uv + node->set_uv(uv_new); + } else if (uv_edit_mode[1]->is_pressed()) { //edit polygon + node->set_polygon(uv_new); + } } break; } uv_edit_draw->update(); + } else if (split_create) { + uv_create_to = mtx.affine_inverse().xform(Vector2(mm->get_position().x, mm->get_position().y)); + uv_edit_draw->update(); } } @@ -407,7 +642,13 @@ void Polygon2DEditor::_uv_draw() { } } - PoolVector<Vector2> uvs = node->get_uv(); + PoolVector<Vector2> uvs; + if (uv_edit_mode[0]->is_pressed()) { //edit uv + uvs = node->get_uv(); + } else { //edit polygon + uvs = node->get_polygon(); + } + Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons"); Rect2 rect(Point2(), mtx.basis_xform(base_tex->get_size())); @@ -416,11 +657,31 @@ void Polygon2DEditor::_uv_draw() { for (int i = 0; i < uvs.size(); i++) { int next = (i + 1) % uvs.size(); - uv_edit_draw->draw_line(mtx.xform(uvs[i]), mtx.xform(uvs[next]), Color(0.9, 0.5, 0.5), 2); + Vector2 next_point = uvs[next]; + if (uv_create && i == uvs.size() - 1) { + next_point = uv_create_to; + } + uv_edit_draw->draw_line(mtx.xform(uvs[i]), mtx.xform(next_point), Color(0.9, 0.5, 0.5), 2); uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5); rect.expand_to(mtx.basis_xform(uvs[i])); } + if (split_create) { + Vector2 from = uvs[uv_drag_index]; + Vector2 to = uv_create_to; + uv_edit_draw->draw_line(mtx.xform(from), mtx.xform(to), Color(0.9, 0.5, 0.5), 2); + } + + PoolVector<int> splits = node->get_splits(); + + for (int i = 0; i < splits.size(); i += 2) { + int idx_from = splits[i]; + int idx_to = splits[i + 1]; + if (idx_from < 0 || idx_to >= uvs.size()) + continue; + uv_edit_draw->draw_line(mtx.xform(uvs[idx_from]), mtx.xform(uvs[idx_to]), Color(0.9, 0.5, 0.5), 2); + } + rect = rect.grow(200); updating_uv_scroll = true; uv_hscroll->set_min(rect.position.x); @@ -449,6 +710,7 @@ void Polygon2DEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_snap_off_y"), &Polygon2DEditor::_set_snap_off_y); ClassDB::bind_method(D_METHOD("_set_snap_step_x"), &Polygon2DEditor::_set_snap_step_x); ClassDB::bind_method(D_METHOD("_set_snap_step_y"), &Polygon2DEditor::_set_snap_step_y); + ClassDB::bind_method(D_METHOD("_uv_edit_mode_select"), &Polygon2DEditor::_uv_edit_mode_select); } Vector2 Polygon2DEditor::snap_point(Vector2 p_target) const { @@ -481,6 +743,34 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) : uv_edit->add_child(uv_main_vb); //uv_edit->set_child_rect(uv_main_vb); HBoxContainer *uv_mode_hb = memnew(HBoxContainer); + + uv_edit_group.instance(); + + uv_edit_mode[0] = memnew(ToolButton); + uv_mode_hb->add_child(uv_edit_mode[0]); + uv_edit_mode[0]->set_toggle_mode(true); + uv_edit_mode[1] = memnew(ToolButton); + uv_mode_hb->add_child(uv_edit_mode[1]); + uv_edit_mode[1]->set_toggle_mode(true); + uv_edit_mode[2] = memnew(ToolButton); + uv_mode_hb->add_child(uv_edit_mode[2]); + uv_edit_mode[2]->set_toggle_mode(true); + + uv_edit_mode[0]->set_text(TTR("UV")); + uv_edit_mode[0]->set_pressed(true); + uv_edit_mode[1]->set_text(TTR("Poly")); + uv_edit_mode[2]->set_text(TTR("Splits")); + + uv_edit_mode[0]->set_button_group(uv_edit_group); + uv_edit_mode[1]->set_button_group(uv_edit_group); + uv_edit_mode[2]->set_button_group(uv_edit_group); + + uv_edit_mode[0]->connect("pressed", this, "_uv_edit_mode_select", varray(0)); + uv_edit_mode[1]->connect("pressed", this, "_uv_edit_mode_select", varray(1)); + uv_edit_mode[2]->connect("pressed", this, "_uv_edit_mode_select", varray(2)); + + uv_mode_hb->add_child(memnew(VSeparator)); + uv_main_vb->add_child(uv_mode_hb); for (int i = 0; i < UV_MODE_MAX; i++) { @@ -491,12 +781,18 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) : uv_button[i]->set_focus_mode(FOCUS_NONE); } - uv_button[0]->set_tooltip(TTR("Move Point") + "\n" + TTR("Ctrl: Rotate") + "\n" + TTR("Shift: Move All") + "\n" + TTR("Shift+Ctrl: Scale")); - uv_button[1]->set_tooltip(TTR("Move Polygon")); - uv_button[2]->set_tooltip(TTR("Rotate Polygon")); - uv_button[3]->set_tooltip(TTR("Scale Polygon")); - - uv_button[0]->set_pressed(true); + uv_button[0]->set_tooltip(TTR("Create Polygon")); + uv_button[1]->set_tooltip(TTR("Move Point") + "\n" + TTR("Ctrl: Rotate") + "\n" + TTR("Shift: Move All") + "\n" + TTR("Shift+Ctrl: Scale")); + uv_button[2]->set_tooltip(TTR("Move Polygon")); + uv_button[3]->set_tooltip(TTR("Rotate Polygon")); + uv_button[4]->set_tooltip(TTR("Scale Polygon")); + uv_button[5]->set_tooltip(TTR("Connect two points to make a split")); + uv_button[6]->set_tooltip(TTR("Select a split to erase it")); + + uv_button[0]->hide(); + uv_button[5]->hide(); + uv_button[6]->hide(); + uv_button[1]->set_pressed(true); HBoxContainer *uv_main_hb = memnew(HBoxContainer); uv_main_vb->add_child(uv_main_hb); uv_edit_draw = memnew(Control); @@ -602,7 +898,9 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) : uv_draw_zoom = 1.0; uv_drag_index = -1; uv_drag = false; + uv_create = false; updating_uv_scroll = false; + split_create = false; error = memnew(AcceptDialog); add_child(error); diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index f1472e4522..8631ffb9a7 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -50,18 +50,24 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { }; enum UVMode { + UV_MODE_CREATE, UV_MODE_EDIT_POINT, UV_MODE_MOVE, UV_MODE_ROTATE, UV_MODE_SCALE, + UV_MODE_ADD_SPLIT, + UV_MODE_REMOVE_SPLIT, UV_MODE_MAX }; + ToolButton *uv_edit_mode[3]; + Ref<ButtonGroup> uv_edit_group; + Polygon2D *node; UVMode uv_mode; AcceptDialog *uv_edit; - ToolButton *uv_button[4]; + ToolButton *uv_button[UV_MODE_MAX]; ToolButton *b_snap_enable; ToolButton *b_snap_grid; Control *uv_edit_draw; @@ -75,8 +81,15 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { Vector2 uv_draw_ofs; float uv_draw_zoom; PoolVector<Vector2> uv_prev; + PoolVector<Vector2> uv_create_uv_prev; + PoolVector<Vector2> uv_create_poly_prev; + PoolVector<int> splits_prev; + + Vector2 uv_create_to; int uv_drag_index; bool uv_drag; + bool uv_create; + bool split_create; UVMode uv_move_current; Vector2 uv_drag_from; bool updating_uv_scroll; @@ -104,6 +117,8 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { void _set_snap_step_x(float p_val); void _set_snap_step_y(float p_val); + void _uv_edit_mode_select(int p_mode); + protected: virtual Node2D *_get_node() const; virtual void _set_node(Node *p_polygon); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index c06531d975..2ce36ee8d5 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -312,7 +312,7 @@ void ScriptEditor::_goto_script_line2(int p_line) { void ScriptEditor::_goto_script_line(REF p_script, int p_line) { Ref<Script> script = Object::cast_to<Script>(*p_script); - if (!script.is_null() && script->get_path().is_resource_file()) { + if (!script.is_null() && script->has_source_code()) { if (edit(p_script, p_line, 0)) { editor->push_item(p_script.ptr()); @@ -1778,6 +1778,20 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool } ERR_FAIL_COND_V(!se, false); + bool highlighter_set = false; + for (int i = 0; i < syntax_highlighters_func_count; i++) { + SyntaxHighlighter *highlighter = syntax_highlighters_funcs[i](); + se->add_syntax_highlighter(highlighter); + + if (!highlighter_set) { + List<String> languages = highlighter->get_supported_languages(); + if (languages.find(p_script->get_language()->get_name())) { + se->set_syntax_highlighter(highlighter); + highlighter_set = true; + } + } + } + tab_container->add_child(se); se->set_edited_script(p_script); se->set_tooltip_request_func("_get_debug_tooltip", this); @@ -2494,6 +2508,14 @@ void ScriptEditor::_open_script_request(const String &p_path) { } } +int ScriptEditor::syntax_highlighters_func_count = 0; +CreateSyntaxHighlighterFunc ScriptEditor::syntax_highlighters_funcs[ScriptEditor::SYNTAX_HIGHLIGHTER_FUNC_MAX]; + +void ScriptEditor::register_create_syntax_highlighter_function(CreateSyntaxHighlighterFunc p_func) { + ERR_FAIL_COND(syntax_highlighters_func_count == SYNTAX_HIGHLIGHTER_FUNC_MAX); + syntax_highlighters_funcs[syntax_highlighters_func_count++] = p_func; +} + int ScriptEditor::script_editor_func_count = 0; CreateScriptEditorFunc ScriptEditor::script_editor_funcs[ScriptEditor::SCRIPT_EDITOR_FUNC_MAX]; @@ -2577,8 +2599,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { waiting_update_names = false; pending_auto_reload = false; auto_reload_running_scripts = false; - members_overview_enabled = true; - help_overview_enabled = true; + members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/show_members_overview"); + help_overview_enabled = EditorSettings::get_singleton()->get("text_editor/help/show_help_index"); editor = p_editor; VBoxContainer *main_container = memnew(VBoxContainer); @@ -2820,9 +2842,9 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { //debugger_gui->hide(); edit_pass = 0; - trim_trailing_whitespace_on_save = false; - convert_indent_on_save = false; - use_space_indentation = false; + trim_trailing_whitespace_on_save = EditorSettings::get_singleton()->get("text_editor/files/trim_trailing_whitespace_on_save"); + convert_indent_on_save = EditorSettings::get_singleton()->get("text_editor/indent/convert_indent_on_save"); + use_space_indentation = EditorSettings::get_singleton()->get("text_editor/indent/type"); ScriptServer::edit_request_func = _open_script_request; diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index bcc604d990..f947351089 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -80,6 +80,9 @@ protected: static void _bind_methods(); public: + virtual void add_syntax_highlighter(SyntaxHighlighter *p_highlighter) = 0; + virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter) = 0; + virtual void apply_code() = 0; virtual Ref<Script> get_edited_script() const = 0; virtual Vector<String> get_functions() = 0; @@ -112,6 +115,7 @@ public: ScriptEditorBase() {} }; +typedef SyntaxHighlighter *(*CreateSyntaxHighlighterFunc)(); typedef ScriptEditorBase *(*CreateScriptEditorFunc)(const Ref<Script> &p_script); class EditorScriptCodeCompletionCache; @@ -214,12 +218,16 @@ class ScriptEditor : public PanelContainer { ToolButton *script_forward; enum { - SCRIPT_EDITOR_FUNC_MAX = 32 + SCRIPT_EDITOR_FUNC_MAX = 32, + SYNTAX_HIGHLIGHTER_FUNC_MAX = 32 }; static int script_editor_func_count; static CreateScriptEditorFunc script_editor_funcs[SCRIPT_EDITOR_FUNC_MAX]; + static int syntax_highlighters_func_count; + static CreateSyntaxHighlighterFunc syntax_highlighters_funcs[SYNTAX_HIGHLIGHTER_FUNC_MAX]; + struct ScriptHistory { Control *control; @@ -399,7 +407,9 @@ public: ScriptEditorDebugger *get_debugger() { return debugger; } void set_live_auto_reload_running_scripts(bool p_enabled); + static void register_create_syntax_highlighter_function(CreateSyntaxHighlighterFunc p_func); static void register_create_script_editor_function(CreateScriptEditorFunc p_func); + ScriptEditor(EditorNode *p_editor); ~ScriptEditor(); }; diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index aeba0ff930..711a313902 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -349,7 +349,12 @@ void ScriptTextEditor::_convert_case(CaseStyle p_case) { int end_col = te->get_selection_to_column(); for (int i = begin; i <= end; i++) { - String new_line = te->get_line(i); + int len = te->get_line(i).length(); + if (i == end) + len -= len - end_col; + if (i == begin) + len -= begin_col; + String new_line = te->get_line(i).substr(i == begin ? begin_col : 0, len); switch (p_case) { case UPPER: { @@ -364,10 +369,10 @@ void ScriptTextEditor::_convert_case(CaseStyle p_case) { } if (i == begin) { - new_line = te->get_line(i).left(begin_col) + new_line.right(begin_col); + new_line = te->get_line(i).left(begin_col) + new_line; } if (i == end) { - new_line = new_line.left(end_col) + te->get_line(i).right(end_col); + new_line = new_line + te->get_line(i).right(end_col); } te->set_line(i, new_line); } @@ -568,6 +573,7 @@ void ScriptTextEditor::set_edited_script(const Ref<Script> &p_script) { ERR_FAIL_COND(!script.is_null()); script = p_script; + _set_theme_for_script(); code_editor->get_text_edit()->set_text(script->get_source_code()); code_editor->get_text_edit()->clear_undo_history(); @@ -575,8 +581,6 @@ void ScriptTextEditor::set_edited_script(const Ref<Script> &p_script) { emit_signal("name_changed"); code_editor->update_line_and_column(); - - _set_theme_for_script(); } void ScriptTextEditor::_validate_script() { @@ -784,6 +788,26 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c emit_signal("go_to_help", "class_method:" + result.class_name + ":" + result.class_member); } break; + case ScriptLanguage::LookupResult::RESULT_CLASS_ENUM: { + + StringName cname = result.class_name; + StringName success; + while (true) { + success = ClassDB::get_integer_constant_enum(cname, result.class_member, true); + if (success != StringName()) { + result.class_name = cname; + cname = ClassDB::get_parent_class(cname); + } else { + break; + } + } + + emit_signal("go_to_help", "class_enum:" + result.class_name + ":" + result.class_member); + + } break; + case ScriptLanguage::LookupResult::RESULT_CLASS_TBD_GLOBALSCOPE: { + emit_signal("go_to_help", "class_global:" + result.class_name + ":" + result.class_member); + } break; } } } @@ -1240,11 +1264,26 @@ void ScriptTextEditor::_edit_option(int p_op) { } } +void ScriptTextEditor::add_syntax_highlighter(SyntaxHighlighter *p_highlighter) { + highlighters[p_highlighter->get_name()] = p_highlighter; + highlighter_menu->get_popup()->add_item(p_highlighter->get_name()); +} + +void ScriptTextEditor::set_syntax_highlighter(SyntaxHighlighter *p_highlighter) { + TextEdit *te = code_editor->get_text_edit(); + te->_set_syntax_highlighting(p_highlighter); +} + +void ScriptTextEditor::_change_syntax_highlighter(int p_idx) { + set_syntax_highlighter(highlighters[highlighter_menu->get_popup()->get_item_text(p_idx)]); +} + void ScriptTextEditor::_bind_methods() { ClassDB::bind_method("_validate_script", &ScriptTextEditor::_validate_script); ClassDB::bind_method("_load_theme_settings", &ScriptTextEditor::_load_theme_settings); ClassDB::bind_method("_breakpoint_toggled", &ScriptTextEditor::_breakpoint_toggled); + ClassDB::bind_method("_change_syntax_highlighter", &ScriptTextEditor::_change_syntax_highlighter); ClassDB::bind_method("_edit_option", &ScriptTextEditor::_edit_option); ClassDB::bind_method("_goto_line", &ScriptTextEditor::_goto_line); ClassDB::bind_method("_lookup_symbol", &ScriptTextEditor::_lookup_symbol); @@ -1630,6 +1669,14 @@ ScriptTextEditor::ScriptTextEditor() { edit_hb->add_child(edit_menu); + highlighters["Standard"] = NULL; + + highlighter_menu = memnew(MenuButton); + highlighter_menu->set_text(TTR("Syntax Highlighter")); + highlighter_menu->get_popup()->add_item("Standard"); + highlighter_menu->get_popup()->connect("id_pressed", this, "_change_syntax_highlighter"); + edit_hb->add_child(highlighter_menu); + quick_open = memnew(ScriptEditorQuickOpen); add_child(quick_open); quick_open->connect("goto_line", this, "_goto_line"); diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index 22e8fbce25..eb52d2593a 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -49,6 +49,7 @@ class ScriptTextEditor : public ScriptEditorBase { HBoxContainer *edit_hb; MenuButton *edit_menu; + MenuButton *highlighter_menu; MenuButton *search_menu; PopupMenu *context_menu; @@ -125,6 +126,9 @@ protected: void _notification(int p_what); static void _bind_methods(); + Map<String, SyntaxHighlighter *> highlighters; + void _change_syntax_highlighter(int p_idx); + void _edit_option(int p_op); void _make_context_menu(bool p_selection, bool p_color, bool p_can_fold, bool p_is_folded); void _text_edit_gui_input(const Ref<InputEvent> &ev); @@ -145,6 +149,9 @@ protected: void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); public: + virtual void add_syntax_highlighter(SyntaxHighlighter *p_highlighter); + virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter); + virtual void apply_code(); virtual Ref<Script> get_edited_script() const; virtual Vector<String> get_functions(); diff --git a/editor/plugins/shader_graph_editor_plugin.cpp b/editor/plugins/shader_graph_editor_plugin.cpp index 59085c203f..e1d28cc215 100644 --- a/editor/plugins/shader_graph_editor_plugin.cpp +++ b/editor/plugins/shader_graph_editor_plugin.cpp @@ -2769,8 +2769,6 @@ void ShaderGraphEditor::_popup_requested(const Vector2 &p_position) popup->set_global_position(p_position); popup->set_size( Size2( 200, 0) ); popup->popup(); - popup->call_deferred("grab_click_focus"); - popup->set_invalidate_click_until_motion(); } void ShaderGraphEditor::_notification(int p_what) { diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp new file mode 100644 index 0000000000..6bf94b95eb --- /dev/null +++ b/editor/plugins/skeleton_2d_editor_plugin.cpp @@ -0,0 +1,115 @@ +#include "skeleton_2d_editor_plugin.h" + +#include "canvas_item_editor_plugin.h" +#include "scene/2d/mesh_instance_2d.h" +#include "scene/gui/box_container.h" +#include "thirdparty/misc/clipper.hpp" + +void Skeleton2DEditor::_node_removed(Node *p_node) { + + if (p_node == node) { + node = NULL; + options->hide(); + } +} + +void Skeleton2DEditor::edit(Skeleton2D *p_sprite) { + + node = p_sprite; +} + +void Skeleton2DEditor::_menu_option(int p_option) { + + switch (p_option) { + case MENU_OPTION_MAKE_REST: { + + if (node->get_bone_count() == 0) { + err_dialog->set_text(TTR("This skeleton has no bones, create some children Bone2D nodes.")); + err_dialog->popup_centered_minsize(); + return; + } + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Create Rest Pose from Bones"); + for (int i = 0; i < node->get_bone_count(); i++) { + Bone2D *bone = node->get_bone(i); + ur->add_do_method(bone, "set_rest", bone->get_transform()); + ur->add_undo_method(bone, "set_rest", bone->get_rest()); + } + ur->commit_action(); + + } break; + case MENU_OPTION_SET_REST: { + if (node->get_bone_count() == 0) { + err_dialog->set_text(TTR("This skeleton has no bones, create some children Bone2D nodes.")); + err_dialog->popup_centered_minsize(); + return; + } + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Set Rest Pose to Bones"); + for (int i = 0; i < node->get_bone_count(); i++) { + Bone2D *bone = node->get_bone(i); + ur->add_do_method(bone, "set_transform", bone->get_rest()); + ur->add_undo_method(bone, "set_transform", bone->get_transform()); + } + ur->commit_action(); + + } break; + } +} + +void Skeleton2DEditor::_bind_methods() { + + ClassDB::bind_method("_menu_option", &Skeleton2DEditor::_menu_option); +} + +Skeleton2DEditor::Skeleton2DEditor() { + + options = memnew(MenuButton); + + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(options); + + options->set_text(TTR("Skeleton2D")); + options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Skeleton2D", "EditorIcons")); + + options->get_popup()->add_item(TTR("Make Rest Pose (From Bones)"), MENU_OPTION_MAKE_REST); + options->get_popup()->add_separator(); + options->get_popup()->add_item(TTR("Set Bones to Rest Pose"), MENU_OPTION_SET_REST); + + options->get_popup()->connect("id_pressed", this, "_menu_option"); + + err_dialog = memnew(AcceptDialog); + add_child(err_dialog); +} + +void Skeleton2DEditorPlugin::edit(Object *p_object) { + + sprite_editor->edit(Object::cast_to<Skeleton2D>(p_object)); +} + +bool Skeleton2DEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("Skeleton2D"); +} + +void Skeleton2DEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + sprite_editor->options->show(); + } else { + + sprite_editor->options->hide(); + sprite_editor->edit(NULL); + } +} + +Skeleton2DEditorPlugin::Skeleton2DEditorPlugin(EditorNode *p_node) { + + editor = p_node; + sprite_editor = memnew(Skeleton2DEditor); + editor->get_viewport()->add_child(sprite_editor); + + //sprite_editor->options->hide(); +} + +Skeleton2DEditorPlugin::~Skeleton2DEditorPlugin() { +} diff --git a/editor/plugins/skeleton_2d_editor_plugin.h b/editor/plugins/skeleton_2d_editor_plugin.h new file mode 100644 index 0000000000..bbe2a3a6f2 --- /dev/null +++ b/editor/plugins/skeleton_2d_editor_plugin.h @@ -0,0 +1,55 @@ +#ifndef SKELETON_2D_EDITOR_PLUGIN_H +#define SKELETON_2D_EDITOR_PLUGIN_H + +#include "editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "scene/2d/skeleton_2d.h" +#include "scene/gui/spin_box.h" + +class Skeleton2DEditor : public Control { + + GDCLASS(Skeleton2DEditor, Control); + + enum Menu { + MENU_OPTION_MAKE_REST, + MENU_OPTION_SET_REST, + }; + + Skeleton2D *node; + + MenuButton *options; + AcceptDialog *err_dialog; + + void _menu_option(int p_option); + + //void _create_uv_lines(); + friend class Skeleton2DEditorPlugin; + +protected: + void _node_removed(Node *p_node); + static void _bind_methods(); + +public: + void edit(Skeleton2D *p_sprite); + Skeleton2DEditor(); +}; + +class Skeleton2DEditorPlugin : public EditorPlugin { + + GDCLASS(Skeleton2DEditorPlugin, EditorPlugin); + + Skeleton2DEditor *sprite_editor; + EditorNode *editor; + +public: + virtual String get_name() const { return "Skeleton2D"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_object); + virtual bool handles(Object *p_object) const; + virtual void make_visible(bool p_visible); + + Skeleton2DEditorPlugin(EditorNode *p_node); + ~Skeleton2DEditorPlugin(); +}; + +#endif // SKELETON_2D_EDITOR_PLUGIN_H diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 9e7bfd5787..9d7c582e0e 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -886,8 +886,6 @@ void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> b) { selection_menu->set_global_position(b->get_global_position()); selection_menu->popup(); - selection_menu->call_deferred("grab_click_focus"); - selection_menu->set_invalidate_click_until_motion(); } } @@ -1907,8 +1905,13 @@ void SpatialEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, con real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity"); real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); + bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y-axis"); - cursor.x_rot += p_relative.y * radians_per_pixel; + if (invert_y_axis) { + cursor.x_rot -= p_relative.y * radians_per_pixel; + } else { + cursor.x_rot += p_relative.y * radians_per_pixel; + } cursor.y_rot += p_relative.x * radians_per_pixel; if (cursor.x_rot > Math_PI / 2.0) cursor.x_rot = Math_PI / 2.0; @@ -1925,11 +1928,16 @@ void SpatialEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, cons if (!orthogonal) { real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity"); real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); + bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y-axis"); // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag". Transform prev_camera_transform = to_camera_transform(cursor); - cursor.x_rot += p_relative.y * radians_per_pixel; + if (invert_y_axis) { + cursor.x_rot -= p_relative.y * radians_per_pixel; + } else { + cursor.x_rot += p_relative.y * radians_per_pixel; + } cursor.y_rot += p_relative.x * radians_per_pixel; if (cursor.x_rot > Math_PI / 2.0) cursor.x_rot = Math_PI / 2.0; @@ -3343,14 +3351,14 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/front_view"), VIEW_FRONT); view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/rear_view"), VIEW_REAR); view_menu->get_popup()->add_separator(); - view_menu->get_popup()->add_check_item(TTR("Perspective") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_PERSPECTIVE); - view_menu->get_popup()->add_check_item(TTR("Orthogonal") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_ORTHOGONAL); + view_menu->get_popup()->add_radio_check_item(TTR("Perspective") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_PERSPECTIVE); + view_menu->get_popup()->add_radio_check_item(TTR("Orthogonal") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_ORTHOGONAL); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), true); view_menu->get_popup()->add_separator(); - view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_normal", TTR("Display Normal")), VIEW_DISPLAY_NORMAL); - view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_wireframe", TTR("Display Wireframe")), VIEW_DISPLAY_WIREFRAME); - view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_overdraw", TTR("Display Overdraw")), VIEW_DISPLAY_OVERDRAW); - view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_unshaded", TTR("Display Unshaded")), VIEW_DISPLAY_SHADELESS); + view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_normal", TTR("Display Normal")), VIEW_DISPLAY_NORMAL); + view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_wireframe", TTR("Display Wireframe")), VIEW_DISPLAY_WIREFRAME); + view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_overdraw", TTR("Display Overdraw")), VIEW_DISPLAY_OVERDRAW); + view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_unshaded", TTR("Display Unshaded")), VIEW_DISPLAY_SHADELESS); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), true); view_menu->get_popup()->add_separator(); view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_environment", TTR("View Environment")), VIEW_ENVIRONMENT); @@ -5101,12 +5109,12 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { accept = memnew(AcceptDialog); editor->get_gui_base()->add_child(accept); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KEY_MASK_CMD + KEY_1), MENU_VIEW_USE_1_VIEWPORT); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports", TTR("3 Viewports"), KEY_MASK_CMD + KEY_3), MENU_VIEW_USE_3_VIEWPORTS); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports_alt", TTR("3 Viewports (Alt)"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_3), MENU_VIEW_USE_3_VIEWPORTS_ALT); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/4_viewports", TTR("4 Viewports"), KEY_MASK_CMD + KEY_4), MENU_VIEW_USE_4_VIEWPORTS); + p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KEY_MASK_CMD + KEY_1), MENU_VIEW_USE_1_VIEWPORT); + p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS); + p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT); + p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports", TTR("3 Viewports"), KEY_MASK_CMD + KEY_3), MENU_VIEW_USE_3_VIEWPORTS); + p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports_alt", TTR("3 Viewports (Alt)"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_3), MENU_VIEW_USE_3_VIEWPORTS_ALT); + p->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/4_viewports", TTR("4 Viewports"), KEY_MASK_CMD + KEY_4), MENU_VIEW_USE_4_VIEWPORTS); p->add_separator(); p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index d8d0a6f013..71a3c90795 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -458,8 +458,6 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) { List<StringName> anim_names; - anim_names.sort_custom<StringName::AlphCompare>(); - frames->get_animation_list(&anim_names); anim_names.sort_custom<StringName::AlphCompare>(); diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 215d2ca551..5ba3931689 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -57,8 +57,9 @@ void TextureRegionEditor::_region_draw() { base_tex = obj_styleBox->get_texture(); else if (atlas_tex.is_valid()) base_tex = atlas_tex->get_atlas(); - else if (tile_set.is_valid() && selected_tile != -1) + else if (tile_set.is_valid() && selected_tile != -1 && tile_set->has_tile(selected_tile)) base_tex = tile_set->tile_get_texture(selected_tile); + if (base_tex.is_null()) return; @@ -600,6 +601,7 @@ void TextureRegionEditor::apply_rect(const Rect2 &rect) { void TextureRegionEditor::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_READY: { zoom_out->set_icon(get_icon("ZoomLess", "EditorIcons")); zoom_reset->set_icon(get_icon("ZoomReset", "EditorIcons")); @@ -688,10 +690,11 @@ void TextureRegionEditor::_edit_region() { texture = obj_styleBox->get_texture(); else if (atlas_tex.is_valid()) texture = atlas_tex->get_atlas(); - else if (tile_set.is_valid() && selected_tile != -1) + else if (tile_set.is_valid() && selected_tile != -1 && tile_set->has_tile(selected_tile)) texture = tile_set->tile_get_texture(selected_tile); if (texture.is_null()) { + edit_draw->update(); return; } @@ -780,9 +783,11 @@ TextureRegionEditor::TextureRegionEditor(EditorNode *p_editor) { tile_set = Ref<TileSet>(NULL); editor = p_editor; undo_redo = editor->get_undo_redo(); + selected_tile = -1; snap_step = Vector2(10, 10); snap_separation = Vector2(0, 0); + snap_mode = SNAP_NONE; edited_margin = -1; drag_index = -1; drag = false; @@ -800,12 +805,10 @@ TextureRegionEditor::TextureRegionEditor(EditorNode *p_editor) { snap_mode_button->set_text(TTR("<None>")); PopupMenu *p = snap_mode_button->get_popup(); p->set_hide_on_checkable_item_selection(false); - p->add_item(TTR("<None>"), 0); - p->add_item(TTR("Pixel Snap"), 1); - p->add_item(TTR("Grid Snap"), 2); - p->add_item(TTR("Auto Slice"), 3); - for (int i = 0; i < 4; i++) - p->set_item_as_checkable(i, true); + p->add_radio_check_item(TTR("<None>"), 0); + p->add_radio_check_item(TTR("Pixel Snap"), 1); + p->add_radio_check_item(TTR("Grid Snap"), 2); + p->add_radio_check_item(TTR("Auto Slice"), 3); p->set_item_checked(0, true); p->connect("id_pressed", this, "_set_snap_mode"); hb_grid = memnew(HBoxContainer); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index f51e691be3..550dfb3ae1 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -244,7 +244,7 @@ void ThemeEditor::_save_template_cbk(String fname) { file->store_line("; "); file->store_line("; ******************* "); file->store_line("; "); - file->store_line("; Template Generated Using: " + String(VERSION_MKSTRING)); + file->store_line("; Template Generated Using: " + String(VERSION_FULL_BUILD)); file->store_line("; "); file->store_line("; "); file->store_line(""); @@ -692,6 +692,10 @@ ThemeEditor::ThemeEditor() { test_menu_button->get_popup()->add_check_item(TTR("Check Item")); test_menu_button->get_popup()->add_check_item(TTR("Checked Item")); test_menu_button->get_popup()->set_item_checked(2, true); + test_menu_button->get_popup()->add_separator(); + test_menu_button->get_popup()->add_check_item(TTR("Radio Item")); + test_menu_button->get_popup()->add_radio_check_item(TTR("Checked Radio Item")); + test_menu_button->get_popup()->set_item_checked(5, true); first_vb->add_child(test_menu_button); OptionButton *test_option_button = memnew(OptionButton); diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index c97e949403..14c584fa35 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -48,6 +48,20 @@ void TileMapEditor::_notification(int p_what) { } break; + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + + bool new_show_tile_info = EditorSettings::get_singleton()->get("editors/tile_map/show_tile_info_on_hover"); + if (new_show_tile_info != show_tile_info) { + show_tile_info = new_show_tile_info; + tile_info->set_visible(show_tile_info); + } + + if (is_visible_in_tree()) { + _update_palette(); + } + + } // fallthrough + case NOTIFICATION_ENTER_TREE: { transp->set_icon(get_icon("Transpose", "EditorIcons")); @@ -60,19 +74,14 @@ void TileMapEditor::_notification(int p_what) { search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons")); - } break; + PopupMenu *p = options->get_popup(); + p->set_item_icon(p->get_item_index(OPTION_PAINTING), get_icon("Edit", "EditorIcons")); + p->set_item_icon(p->get_item_index(OPTION_PICK_TILE), get_icon("ColorPick", "EditorIcons")); + p->set_item_icon(p->get_item_index(OPTION_SELECT), get_icon("ToolSelect", "EditorIcons")); + p->set_item_icon(p->get_item_index(OPTION_MOVE), get_icon("ToolMove", "EditorIcons")); + p->set_item_icon(p->get_item_index(OPTION_DUPLICATE), get_icon("Duplicate", "EditorIcons")); + p->set_item_icon(p->get_item_index(OPTION_ERASE_SELECTION), get_icon("Remove", "EditorIcons")); - case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - - bool new_show_tile_info = EditorSettings::get_singleton()->get("editors/tile_map/show_tile_info_on_hover"); - if (new_show_tile_info != show_tile_info) { - show_tile_info = new_show_tile_info; - tile_info->set_visible(show_tile_info); - } - - if (is_visible_in_tree()) { - _update_palette(); - } } break; } } @@ -139,6 +148,23 @@ void TileMapEditor::_menu_option(int p_option) { canvas_item_editor->update(); } break; + case OPTION_FIX_INVALID: { + + undo_redo->create_action(TTR("Fix Invalid Tiles")); + undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + node->fix_invalid_tiles(); + undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); + undo_redo->commit_action(); + + } break; + case OPTION_MOVE: { + + if (selection_active) { + _update_copydata(); + tool = TOOL_MOVING; + canvas_item_editor->update(); + } + } break; } } @@ -812,6 +838,29 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { copydata.clear(); canvas_item_editor->update(); + } else if (tool == TOOL_MOVING) { + + Point2 ofs = over_tile - rectangle.position; + + undo_redo->create_action(TTR("Move")); + undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data")); + for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) { + for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) { + + _set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false); + } + } + for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) { + + _set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose); + } + undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data")); + undo_redo->commit_action(); + + copydata.clear(); + selection_active = false; + + canvas_item_editor->update(); } else if (tool == TOOL_SELECTING) { @@ -871,6 +920,16 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return true; } + if (tool == TOOL_MOVING) { + + tool = TOOL_NONE; + copydata.clear(); + + canvas_item_editor->update(); + + return true; + } + if (tool == TOOL_NONE) { paint_undo.clear(); @@ -1078,7 +1137,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (k->get_scancode() == KEY_ESCAPE) { - if (tool == TOOL_DUPLICATING) + if (tool == TOOL_DUPLICATING || tool == TOOL_MOVING) copydata.clear(); else if (tool == TOOL_SELECTING || selection_active) selection_active = false; @@ -1133,6 +1192,14 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return true; } } + if (ED_IS_SHORTCUT("tile_map_editor/move_selection", p_event)) { + if (selection_active) { + _update_copydata(); + tool = TOOL_MOVING; + canvas_item_editor->update(); + return true; + } + } if (ED_IS_SHORTCUT("tile_map_editor/find_tile", p_event)) { search_box->select_all(); search_box->grab_focus(); @@ -1142,18 +1209,21 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (ED_IS_SHORTCUT("tile_map_editor/mirror_x", p_event)) { flip_h = !flip_h; mirror_x->set_pressed(flip_h); + _update_transform_buttons(); canvas_item_editor->update(); return true; } if (ED_IS_SHORTCUT("tile_map_editor/mirror_y", p_event)) { flip_v = !flip_v; mirror_y->set_pressed(flip_v); + _update_transform_buttons(); canvas_item_editor->update(); return true; } if (ED_IS_SHORTCUT("tile_map_editor/transpose", p_event)) { transpose = !transpose; transp->set_pressed(transpose); + _update_transform_buttons(); canvas_item_editor->update(); return true; } @@ -1326,7 +1396,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) { _draw_cell(id, Point2i(j, i), flip_h, flip_v, transpose, xform); } } - } else if (tool == TOOL_DUPLICATING) { + } else if (tool == TOOL_DUPLICATING || tool == TOOL_MOVING) { if (copydata.empty()) return; @@ -1511,8 +1581,8 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { bucket_cache_tile = -1; bucket_cache_visited = 0; - ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase selection"), KEY_DELETE); - ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find tile"), KEY_MASK_CMD + KEY_F); + ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase Selection"), KEY_DELETE); + ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find Tile"), KEY_MASK_CMD + KEY_F); ED_SHORTCUT("tile_map_editor/transpose", TTR("Transpose"), KEY_T); ED_SHORTCUT("tile_map_editor/mirror_x", TTR("Mirror X"), KEY_A); ED_SHORTCUT("tile_map_editor/mirror_y", TTR("Mirror Y"), KEY_S); @@ -1573,8 +1643,11 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { p->add_item(TTR("Pick Tile"), OPTION_PICK_TILE, KEY_CONTROL); p->add_separator(); p->add_shortcut(ED_SHORTCUT("tile_map_editor/select", TTR("Select"), KEY_MASK_CMD + KEY_B), OPTION_SELECT); + p->add_shortcut(ED_SHORTCUT("tile_map_editor/move_selection", TTR("Move Selection"), KEY_MASK_CMD + KEY_M), OPTION_MOVE); p->add_shortcut(ED_SHORTCUT("tile_map_editor/duplicate_selection", TTR("Duplicate Selection"), KEY_MASK_CMD + KEY_D), OPTION_DUPLICATE); p->add_shortcut(ED_GET_SHORTCUT("tile_map_editor/erase_selection"), OPTION_ERASE_SELECTION); + p->add_separator(); + p->add_item(TTR("Fix Invalid Tiles"), OPTION_FIX_INVALID); p->connect("id_pressed", this, "_menu_option"); diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h index 0a937e200e..3257901c88 100644 --- a/editor/plugins/tile_map_editor_plugin.h +++ b/editor/plugins/tile_map_editor_plugin.h @@ -61,6 +61,7 @@ class TileMapEditor : public VBoxContainer { TOOL_BUCKET, TOOL_PICKING, TOOL_DUPLICATING, + TOOL_MOVING }; enum Options { @@ -71,6 +72,8 @@ class TileMapEditor : public VBoxContainer { OPTION_DUPLICATE, OPTION_ERASE_SELECTION, OPTION_PAINTING, + OPTION_FIX_INVALID, + OPTION_MOVE }; TileMap *node; diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index 71c0d8a782..2311439728 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -242,6 +242,7 @@ void TileSetEditor::_bind_methods() { ClassDB::bind_method("_name_dialog_confirm", &TileSetEditor::_name_dialog_confirm); ClassDB::bind_method("_on_tile_list_selected", &TileSetEditor::_on_tile_list_selected); ClassDB::bind_method("_on_edit_mode_changed", &TileSetEditor::_on_edit_mode_changed); + ClassDB::bind_method("_on_workspace_overlay_draw", &TileSetEditor::_on_workspace_overlay_draw); ClassDB::bind_method("_on_workspace_draw", &TileSetEditor::_on_workspace_draw); ClassDB::bind_method("_on_workspace_input", &TileSetEditor::_on_workspace_input); ClassDB::bind_method("_on_tool_clicked", &TileSetEditor::_on_tool_clicked); @@ -256,7 +257,7 @@ void TileSetEditor::_bind_methods() { } void TileSetEditor::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { tools[TOOL_SELECT]->set_icon(get_icon("ToolSelect", "EditorIcons")); tools[BITMASK_COPY]->set_icon(get_icon("Duplicate", "EditorIcons")); tools[BITMASK_PASTE]->set_icon(get_icon("Override", "EditorIcons")); @@ -401,7 +402,7 @@ void TileSetEditor::initialize_bottom_editor() { p.push_back((int)SHAPE_DELETE); tools[SHAPE_DELETE]->connect("pressed", this, "_on_tool_clicked", p); tool_containers[TOOLBAR_SHAPE]->add_child(tools[SHAPE_DELETE]); - tool_containers[TOOLBAR_SHAPE]->add_change_receptor(memnew(VSeparator)); + tool_containers[TOOLBAR_SHAPE]->add_child(memnew(VSeparator)); tools[SHAPE_KEEP_INSIDE_TILE] = memnew(ToolButton); tools[SHAPE_KEEP_INSIDE_TILE]->set_toggle_mode(true); tools[SHAPE_KEEP_INSIDE_TILE]->set_pressed(true); @@ -519,10 +520,15 @@ void TileSetEditor::initialize_bottom_editor() { workspace_container = memnew(Control); scroll->add_child(workspace_container); + workspace_overlay = memnew(Control); + workspace_overlay->connect("draw", this, "_on_workspace_overlay_draw"); + workspace_container->add_child(workspace_overlay); + workspace = memnew(Control); workspace->connect("draw", this, "_on_workspace_draw"); workspace->connect("gui_input", this, "_on_workspace_input"); - workspace_container->add_child(workspace); + workspace->set_draw_behind_parent(true); + workspace_overlay->add_child(workspace); preview = memnew(Sprite); workspace->add_child(preview); @@ -558,9 +564,16 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { add_child(err_dialog); err_dialog->set_title(TTR("Error")); + draw_handles = false; + initialize_bottom_editor(); } +TileSetEditor::~TileSetEditor() { + if (helper) + memdelete(helper); +} + void TileSetEditor::_on_tile_list_selected(int p_index) { if (get_current_tile() >= 0) { current_item_index = p_index; @@ -734,9 +747,23 @@ void TileSetEditor::_on_workspace_draw() { } } } + workspace_overlay->update(); } -#define MIN_DISTANCE_SQUARED 10 +void TileSetEditor::_on_workspace_overlay_draw() { + + int t_id = get_current_tile(); + if (t_id < 0 || !draw_handles) + return; + + Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons"); + + for (int i = 0; i < current_shape.size(); i++) { + workspace_overlay->draw_texture(handle, current_shape[i] * workspace->get_scale().x - handle->get_size() * 0.5); + } +} + +#define MIN_DISTANCE_SQUARED 6 void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { if (get_current_tile() >= 0 && !tileset.is_null()) { @@ -1157,15 +1184,18 @@ void TileSetEditor::_on_tool_clicked(int p_tool) { scale /= 2; workspace->set_scale(Vector2(scale, scale)); workspace_container->set_custom_minimum_size(preview->get_region_rect().size * scale); + workspace_overlay->set_custom_minimum_size(preview->get_region_rect().size * scale); } } else if (p_tool == ZOOM_1) { workspace->set_scale(Vector2(1, 1)); workspace_container->set_custom_minimum_size(preview->get_region_rect().size); + workspace_overlay->set_custom_minimum_size(preview->get_region_rect().size); } else if (p_tool == ZOOM_IN) { float scale = workspace->get_scale().x; scale *= 2; workspace->set_scale(Vector2(scale, scale)); workspace_container->set_custom_minimum_size(preview->get_region_rect().size * scale); + workspace_overlay->set_custom_minimum_size(preview->get_region_rect().size * scale); } else if (p_tool == TOOL_SELECT) { if (creating_shape) { //Cancel Creation @@ -1287,6 +1317,8 @@ void TileSetEditor::draw_polygon_shapes() { if (t_id < 0) return; + draw_handles = false; + switch (edit_mode) { case EDITMODE_COLLISION: { Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(t_id); @@ -1334,9 +1366,7 @@ void TileSetEditor::draw_polygon_shapes() { } if (shape == edited_collision_shape) { - for (int j = 0; j < current_shape.size(); j++) { - workspace->draw_circle(current_shape[j], 8 / workspace->get_scale().x, Color(1, 0, 0, 0.7f)); - } + draw_handles = true; } } } @@ -1362,9 +1392,7 @@ void TileSetEditor::draw_polygon_shapes() { } workspace->draw_line(shape->get_polygon()[shape->get_polygon().size() - 1], shape->get_polygon()[0], c_border, 1, true); if (shape == edited_occlusion_shape) { - for (int j = 0; j < current_shape.size(); j++) { - workspace->draw_circle(current_shape[j], 8 / workspace->get_scale().x, Color(1, 0, 0)); - } + draw_handles = true; } } } else { @@ -1407,9 +1435,7 @@ void TileSetEditor::draw_polygon_shapes() { } workspace->draw_line(shape->get_polygon()[shape->get_polygon().size() - 1] + anchor, shape->get_polygon()[0] + anchor, c_border, 1, true); if (shape == edited_occlusion_shape) { - for (int j = 0; j < current_shape.size(); j++) { - workspace->draw_circle(current_shape[j], 8 / workspace->get_scale().x, Color(1, 0, 0)); - } + draw_handles = true; } } } @@ -1440,9 +1466,7 @@ void TileSetEditor::draw_polygon_shapes() { workspace->draw_line(vertices[shape->get_polygon(0)[j]], vertices[shape->get_polygon(0)[j + 1]], c_border, 1, true); } if (shape == edited_navigation_shape) { - for (int j = 0; j < current_shape.size(); j++) { - workspace->draw_circle(current_shape[j], 8 / workspace->get_scale().x, Color(1, 0, 0)); - } + draw_handles = true; } } } @@ -1489,9 +1513,7 @@ void TileSetEditor::draw_polygon_shapes() { workspace->draw_line(vertices[shape->get_polygon(0)[j]] + anchor, vertices[shape->get_polygon(0)[j + 1]] + anchor, c_border, 1, true); } if (shape == edited_navigation_shape) { - for (int j = 0; j < current_shape.size(); j++) { - workspace->draw_circle(current_shape[j], 8 / workspace->get_scale().x, Color(1, 0, 0)); - } + draw_handles = true; } } } @@ -1804,6 +1826,8 @@ bool TileSetEditorHelper::_get(const StringName &p_name, Variant &r_ret) const { if (selected_tile < 0 || tileset.is_null()) return false; + if (!tileset->has_tile(selected_tile)) + return false; String name = p_name.operator String(); bool v = false; @@ -1828,6 +1852,7 @@ void TileSetEditorHelper::_get_property_list(List<PropertyInfo> *p_list) const { TileSetEditorHelper::TileSetEditorHelper(TileSetEditor *p_tileset_editor) { tileset_editor = p_tileset_editor; + selected_tile = -1; } void TileSetEditorPlugin::edit(Object *p_node) { diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h index 0404c5236a..4894d641a3 100644 --- a/editor/plugins/tile_set_editor_plugin.h +++ b/editor/plugins/tile_set_editor_plugin.h @@ -91,6 +91,8 @@ class TileSetEditor : public Control { Sprite *preview; ScrollContainer *scroll; Control *workspace_container; + bool draw_handles; + Control *workspace_overlay; Control *workspace; Button *tool_editmode[EDITMODE_MAX]; HBoxContainer *tool_containers[TOOLBAR_MAX]; @@ -155,10 +157,12 @@ public: static Error update_library_file(Node *p_base_scene, Ref<TileSet> ml, bool p_merge = true); TileSetEditor(EditorNode *p_editor); + ~TileSetEditor(); private: void _on_tile_list_selected(int p_index); void _on_edit_mode_changed(int p_edit_mode); + void _on_workspace_overlay_draw(); void _on_workspace_draw(); void _on_workspace_input(const Ref<InputEvent> &p_ie); void _on_tool_clicked(int p_tool); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index d15a37a19c..4dbd9d500e 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -56,6 +56,12 @@ void ProjectExportDialog::_notification(int p_what) { case NOTIFICATION_POPUP_HIDE: { EditorSettings::get_singleton()->set("interface/dialogs/export_bounds", get_rect()); } break; + case NOTIFICATION_THEME_CHANGED: { + delete_preset->set_icon(get_icon("Remove", "EditorIcons")); + Control *panel = custom_feature_display->get_parent_control(); + if (panel) + panel->add_style_override("panel", get_stylebox("bg", "Tree")); + } break; } } diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index bd700342f6..de98c89db5 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -689,7 +689,7 @@ void ProjectManager::_notification(int p_what) { } break; case NOTIFICATION_READY: { - if (scroll_children->get_child_count() == 0) + if (scroll_children->get_child_count() == 0 && StreamPeerSSL::is_available()) open_templates->popup_centered_minsize(); } break; case NOTIFICATION_VISIBILITY_CHANGED: { @@ -1517,18 +1517,43 @@ ProjectManager::ProjectManager() { EditorSettings::get_singleton()->set_optimize_save(false); //just write settings as they came { - int dpi_mode = EditorSettings::get_singleton()->get("interface/editor/hidpi_mode"); - if (dpi_mode == 0) { - const int screen = OS::get_singleton()->get_current_screen(); - editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0); - } else if (dpi_mode == 1) { - editor_set_scale(0.75); - } else if (dpi_mode == 2) { - editor_set_scale(1.0); - } else if (dpi_mode == 3) { - editor_set_scale(1.5); - } else if (dpi_mode == 4) { - editor_set_scale(2.0); + int display_scale = EditorSettings::get_singleton()->get("interface/editor/display_scale"); + float custom_display_scale = EditorSettings::get_singleton()->get("interface/editor/custom_display_scale"); + + switch (display_scale) { + case 0: { + // Try applying a suitable display scale automatically + const int screen = OS::get_singleton()->get_current_screen(); + editor_set_scale(OS::get_singleton()->get_screen_dpi(screen) >= 192 && OS::get_singleton()->get_screen_size(screen).x > 2000 ? 2.0 : 1.0); + } break; + + case 1: { + editor_set_scale(0.75); + } break; + + case 2: { + editor_set_scale(1.0); + } break; + + case 3: { + editor_set_scale(1.25); + } break; + + case 4: { + editor_set_scale(1.5); + } break; + + case 5: { + editor_set_scale(1.75); + } break; + + case 6: { + editor_set_scale(2.0); + } break; + + default: { + editor_set_scale(custom_display_scale); + } break; } } @@ -1570,7 +1595,7 @@ ProjectManager::ProjectManager() { String hash = String(VERSION_HASH); if (hash.length() != 0) hash = "." + hash.left(7); - l->set_text("v" VERSION_MKSTRING "" + hash); + l->set_text("v" VERSION_FULL_BUILD "" + hash); l->set_align(Label::ALIGN_CENTER); top_hb->add_child(l); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 9625bc19c0..75523cd843 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -110,11 +110,28 @@ void ProjectSettingsEditor::_notification(int p_what) { EditorSettings::get_singleton()->set("interface/dialogs/project_settings_bounds", get_rect()); } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + + search_button->set_icon(get_icon("Search", "EditorIcons")); + clear_button->set_icon(get_icon("Close", "EditorIcons")); + action_add_error->add_color_override("font_color", get_color("error_color", "Editor")); + popup_add->set_item_icon(popup_add->get_item_index(INPUT_KEY), get_icon("Keyboard", "EditorIcons")); + popup_add->set_item_icon(popup_add->get_item_index(INPUT_JOY_BUTTON), get_icon("JoyButton", "EditorIcons")); + popup_add->set_item_icon(popup_add->get_item_index(INPUT_JOY_MOTION), get_icon("JoyAxis", "EditorIcons")); + popup_add->set_item_icon(popup_add->get_item_index(INPUT_MOUSE_BUTTON), get_icon("Mouse", "EditorIcons")); _update_actions(); } break; } } +static bool _validate_action_name(const String &p_name) { + const CharType *cstr = p_name.c_str(); + for (int i = 0; cstr[i]; i++) + if (cstr[i] == '/' || cstr[i] == ':' || cstr[i] == '"' || + cstr[i] == '=' || cstr[i] == '\\' || cstr[i] < 32) + return false; + return true; +} + void ProjectSettingsEditor::_action_selected() { TreeItem *ti = input_editor->get_selected(); @@ -137,12 +154,12 @@ void ProjectSettingsEditor::_action_edited() { if (new_name == old_name) return; - if (new_name.find("/") != -1 || new_name.find(":") != -1 || new_name == "") { + if (new_name == "" || !_validate_action_name(new_name)) { ti->set_text(0, old_name); add_at = "input/" + old_name; - message->set_text(TTR("Invalid action (anything goes but '/' or ':').")); + message->set_text(TTR("Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or '\"'")); message->popup_centered(Size2(300, 100) * EDSCALE); return; } @@ -830,9 +847,9 @@ void ProjectSettingsEditor::_action_check(String p_action) { action_add->set_disabled(true); } else { - if (p_action.find("/") != -1 || p_action.find(":") != -1) { + if (!_validate_action_name(p_action)) { - action_add_error->set_text(TTR("Can't contain '/' or ':'")); + action_add_error->set_text(TTR("Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or '\"'")); action_add_error->show(); action_add->set_disabled(true); return; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 9f0f62592b..b13b238fd7 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -345,17 +345,30 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } break; case TOOL_CLEAR_SCRIPT: { - Node *selected = scene_tree->get_selected(); - if (!selected) - break; - Ref<Script> existing = selected->get_script(); - if (existing.is_valid()) { - const RefPtr empty; - selected->set_script(empty); - _update_script_button(); + List<Node *> selection = editor_selection->get_selected_node_list(); + + if (selection.empty()) + return; + + editor_data->get_undo_redo().create_action(TTR("Clear Script")); + editor_data->get_undo_redo().add_do_method(editor, "push_item", (Script *)NULL); + + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + + Ref<Script> existing = E->get()->get_script(); + if (existing.is_valid()) { + const RefPtr empty; + editor_data->get_undo_redo().add_do_method(E->get(), "set_script", empty); + editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing); + } } + editor_data->get_undo_redo().add_do_method(this, "_update_script_button"); + editor_data->get_undo_redo().add_undo_method(this, "_update_script_button"); + + editor_data->get_undo_redo().commit_action(); + } break; case TOOL_MOVE_UP: case TOOL_MOVE_DOWN: { @@ -903,9 +916,6 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP if (!r_rem_anims) r_rem_anims = &rem_anims; - if (!bool(EDITOR_DEF("editors/animation/autorename_animation_tracks", true))) - return; - if (!p_base) { p_base = edited_scene; @@ -914,7 +924,54 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP if (!p_base) return; - if (Object::cast_to<AnimationPlayer>(p_base)) { + // Renaming node paths used in script instances + if (p_base->get_script_instance()) { + + ScriptInstance *si = p_base->get_script_instance(); + + if (si) { + + List<PropertyInfo> properties; + si->get_property_list(&properties); + + for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { + + String propertyname = E->get().name; + Variant p = p_base->get(propertyname); + if (p.get_type() == Variant::NODE_PATH) { + + // Goes through all paths to check if its matching + for (List<Pair<NodePath, NodePath> >::Element *E = p_renames->front(); E; E = E->next()) { + + NodePath root_path = p_base->get_path(); + + NodePath rel_path_old = root_path.rel_path_to(E->get().first); + + NodePath rel_path_new = E->get().second; + + // if not empty, get new relative path + if (E->get().second != NodePath()) { + rel_path_new = root_path.rel_path_to(E->get().second); + } + + // if old path detected, then it needs to be replaced with the new one + if (p == rel_path_old) { + + editor_data->get_undo_redo().add_do_property(p_base, propertyname, rel_path_new); + editor_data->get_undo_redo().add_undo_property(p_base, propertyname, rel_path_old); + + p_base->set(propertyname, rel_path_new); + break; + } + } + } + } + } + } + + bool autorename_animation_tracks = bool(EDITOR_DEF("editors/animation/autorename_animation_tracks", true)); + + if (autorename_animation_tracks && Object::cast_to<AnimationPlayer>(p_base)) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_base); List<StringName> anims; @@ -1145,7 +1202,30 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V editor_data->get_undo_redo().add_do_method(new_parent, "move_child", node, p_position_in_parent + inc); ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + String old_name = former_names[ni]; String new_name = new_parent->validate_child_name(node); + + // name was modified, fix the path renames + if (old_name.casecmp_to(new_name) != 0) { + + // Fix the to name to have the new name + NodePath old_new_name = path_renames[ni].second; + NodePath new_path; + + Vector<StringName> unfixed_new_names = old_new_name.get_names(); + Vector<StringName> fixed_new_names; + + // Get last name and replace with fixed new name + for (int a = 0; a < (unfixed_new_names.size() - 1); a++) { + fixed_new_names.push_back(unfixed_new_names[a]); + } + fixed_new_names.push_back(new_name); + + NodePath fixed_node_path = NodePath(fixed_new_names, true); + + path_renames[ni].second = fixed_node_path; + } + editor_data->get_undo_redo().add_do_method(sed, "live_debug_reparent_node", edited_scene->get_path_to(node), edited_scene->get_path_to(new_parent), new_name, -1); editor_data->get_undo_redo().add_undo_method(sed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(new_parent)) + "/" + new_name), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index()); @@ -1208,12 +1288,26 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V void SceneTreeDock::_script_created(Ref<Script> p_script) { - Node *selected = scene_tree->get_selected(); - if (!selected) + List<Node *> selected = editor_selection->get_selected_node_list(); + + if (selected.empty()) return; - selected->set_script(p_script.get_ref_ptr()); - editor->push_item(p_script.operator->()); - _update_script_button(); + + editor_data->get_undo_redo().create_action(TTR("Attach Script")); + for (List<Node *>::Element *E = selected.front(); E; E = E->next()) { + + Ref<Script> existing = E->get()->get_script(); + editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script.get_ref_ptr()); + editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing); + } + + editor_data->get_undo_redo().add_do_method(editor, "push_item", p_script.operator->()); + editor_data->get_undo_redo().add_undo_method(editor, "push_item", (Script *)NULL); + + editor_data->get_undo_redo().add_do_method(this, "_update_script_button"); + editor_data->get_undo_redo().add_undo_method(this, "_update_script_button"); + + editor_data->get_undo_redo().commit_action(); } void SceneTreeDock::_delete_confirm() { @@ -1411,6 +1505,7 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node) { Node *n = p_node; Node *newnode = p_by_node; + Node *default_oldnode = Object::cast_to<Node>(ClassDB::instance(n->get_class())); List<PropertyInfo> pinfo; n->get_property_list(&pinfo); @@ -1419,8 +1514,11 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node) { continue; if (E->get().name == "__meta__") continue; - newnode->set(E->get().name, n->get(E->get().name)); + if (default_oldnode->get(E->get().name) != n->get(E->get().name)) { + newnode->set(E->get().name, n->get(E->get().name)); + } } + memdelete(default_oldnode); editor->push_item(NULL); @@ -1665,8 +1763,12 @@ void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) { ERR_FAIL_COND(!scr.is_valid()); Node *n = get_node(p_to); if (n) { - n->set_script(scr.get_ref_ptr()); - _update_script_button(); + editor_data->get_undo_redo().create_action(TTR("Attach Script")); + editor_data->get_undo_redo().add_do_method(n, "set_script", scr); + editor_data->get_undo_redo().add_undo_method(n, "set_script", n->get_script()); + editor_data->get_undo_redo().add_do_method(this, "_update_script_button"); + editor_data->get_undo_redo().add_undo_method(this, "_update_script_button"); + editor_data->get_undo_redo().commit_action(); } } @@ -1759,6 +1861,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { subresources.clear(); menu_subresources->clear(); + menu_subresources->set_size(Size2(1, 1)); _add_children_to_popup(selection.front()->get(), 0); if (menu->get_item_count() > 0) menu->add_separator(); @@ -1803,6 +1906,10 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->set_item_checked(menu->get_item_idx_from_text(TTR("Load As Placeholder")), placeholder); } } + } else { + menu->add_separator(); + menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT); + menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT); } menu->add_separator(); menu->add_icon_shortcut(get_icon("Remove", "EditorIcons"), ED_SHORTCUT("scene_tree/delete", TTR("Delete Node(s)"), KEY_DELETE), TOOL_ERASE); @@ -1921,6 +2028,7 @@ void SceneTreeDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_focus_node"), &SceneTreeDock::_focus_node); ClassDB::bind_method(D_METHOD("_remote_tree_selected"), &SceneTreeDock::_remote_tree_selected); ClassDB::bind_method(D_METHOD("_local_tree_selected"), &SceneTreeDock::_local_tree_selected); + ClassDB::bind_method(D_METHOD("_update_script_button"), &SceneTreeDock::_update_script_button); ClassDB::bind_method(D_METHOD("instance"), &SceneTreeDock::instance); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 8f3113c816..e38347a653 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -550,6 +550,10 @@ void SceneTreeEditor::_notification(int p_what) { get_tree()->disconnect("node_configuration_warning_changed", this, "_warning_changed"); EditorSettings::get_singleton()->disconnect("settings_changed", this, "_editor_settings_changed"); } + if (p_what == NOTIFICATION_THEME_CHANGED) { + + _update_tree(); + } } TreeItem *SceneTreeEditor::_find(TreeItem *p_node, const NodePath &p_path) { diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index b893b098ac..57a003060e 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -41,10 +41,12 @@ void ScriptCreateDialog::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_ENTER_TREE: { path_button->set_icon(get_icon("Folder", "EditorIcons")); parent_browse_button->set_icon(get_icon("Folder", "EditorIcons")); - } + status_panel->add_style_override("panel", get_stylebox("bg", "Tree")); + } break; } } @@ -434,6 +436,13 @@ void ScriptCreateDialog::_path_changed(const String &p_path) { return; } + String path_error = ScriptServer::get_language(language_menu->get_selected())->validate_path(p); + if (path_error != "") { + _msg_path_valid(false, path_error); + _update_dialog(); + return; + } + /* All checks passed */ is_path_valid = true; @@ -609,10 +618,10 @@ ScriptCreateDialog::ScriptCreateDialog() { hb->add_child(path_error_label); vb->add_child(hb); - PanelContainer *pc = memnew(PanelContainer); - pc->set_h_size_flags(Control::SIZE_FILL); - pc->add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("bg", "Tree")); - pc->add_child(vb); + status_panel = memnew(PanelContainer); + status_panel->set_h_size_flags(Control::SIZE_FILL); + status_panel->add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("bg", "Tree")); + status_panel->add_child(vb); /* Margins */ @@ -631,7 +640,7 @@ ScriptCreateDialog::ScriptCreateDialog() { vb->add_child(empty_h->duplicate()); vb->add_child(gc); vb->add_child(empty_h->duplicate()); - vb->add_child(pc); + vb->add_child(status_panel); vb->add_child(empty_h->duplicate()); hb = memnew(HBoxContainer); hb->add_child(empty_v->duplicate()); diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h index 99e5bc9e6a..1ad4a1b7a1 100644 --- a/editor/script_create_dialog.h +++ b/editor/script_create_dialog.h @@ -46,6 +46,7 @@ class ScriptCreateDialog : public ConfirmationDialog { LineEdit *class_name; Label *error_label; Label *path_error_label; + PanelContainer *status_panel; LineEdit *parent_name; Button *parent_browse_button; OptionButton *language_menu; diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index 36df5f6ccc..e9529eb1c0 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -948,7 +948,7 @@ void ScriptEditorDebugger::_notification(int p_what) { inspector->edit(variables); - copy->set_icon(get_icon("Duplicate", "EditorIcons")); + copy->set_icon(get_icon("ActionCopy", "EditorIcons")); step->set_icon(get_icon("DebugStep", "EditorIcons")); next->set_icon(get_icon("DebugNext", "EditorIcons")); @@ -1160,6 +1160,16 @@ void ScriptEditorDebugger::_notification(int p_what) { inspect_scene_tree->add_color_override("relationship_line_color", rl_color); } else inspect_scene_tree->add_constant_override("draw_relationship_lines", 0); + + copy->set_icon(get_icon("ActionCopy", "EditorIcons")); + step->set_icon(get_icon("DebugStep", "EditorIcons")); + next->set_icon(get_icon("DebugNext", "EditorIcons")); + back->set_icon(get_icon("Back", "EditorIcons")); + forward->set_icon(get_icon("Forward", "EditorIcons")); + dobreak->set_icon(get_icon("Pause", "EditorIcons")); + docontinue->set_icon(get_icon("DebugContinue", "EditorIcons")); + vmem_refresh->set_icon(get_icon("Reload", "EditorIcons")); + } break; } } @@ -1646,12 +1656,20 @@ void ScriptEditorDebugger::_error_selected(int p_idx) { md.push_back(st[i + 1]); md.push_back(st[i + 2]); - String str = func + " in " + script.get_file() + ":line " + itos(line); + String str = func; + String tooltip_str = TTR("Function:") + " " + func; + if (script.length() > 0) { + str += " in " + script.get_file(); + tooltip_str = TTR("File:") + " " + script + "\n" + tooltip_str; + if (line > 0) { + str += ":line " + itos(line); + tooltip_str += "\n" + TTR("Line:") + " " + itos(line); + } + } error_stack->add_item(str); error_stack->set_item_metadata(error_stack->get_item_count() - 1, md); - error_stack->set_item_tooltip(error_stack->get_item_count() - 1, - TTR("File:") + " " + script + "\n" + TTR("Function:") + " " + func + "\n" + TTR("Line:") + " " + itos(line)); + error_stack->set_item_tooltip(error_stack->get_item_count() - 1, tooltip_str); } } @@ -1734,7 +1752,7 @@ void ScriptEditorDebugger::_error_list_item_rmb_selected(int p_item, const Vecto bool single_item_selected = error_list->get_selected_items().size() == 1; if (single_item_selected) { - item_menu->add_icon_item(get_icon("CopyNodePath", "EditorIcons"), TTR("Copy Error"), ITEM_MENU_COPY_ERROR); + item_menu->add_icon_item(get_icon("ActionCopy", "EditorIcons"), TTR("Copy Error"), ITEM_MENU_COPY_ERROR); } if (item_menu->get_item_count() > 0) { diff --git a/editor/translations/af.po b/editor/translations/af.po index 9d4ce1e29d..0f5a2b890f 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -2400,12 +2400,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2458,10 +2452,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3634,15 +3624,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4465,6 +4455,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4748,10 +4754,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "" @@ -4764,6 +4766,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5604,11 +5610,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5869,10 +5870,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5894,7 +5891,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5914,10 +5913,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6608,10 +6603,6 @@ msgstr "Hulpbron" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6721,10 +6712,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7148,11 +7135,23 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +msgid "Next Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7160,19 +7159,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7281,6 +7280,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "Skep Intekening" @@ -7297,6 +7300,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7799,6 +7806,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/editor/translations/ar.po b/editor/translations/ar.po index deb49f0619..7e9f894292 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -19,8 +19,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-01-24 11:45+0000\n" -"Last-Translator: anonymous <>\n" +"PO-Revision-Date: 2018-01-30 16:34+0000\n" +"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n" "Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/" "godot/ar/>\n" "Language: ar\n" @@ -2445,12 +2445,6 @@ msgid "Invalid version.txt format inside templates." msgstr "صيغة غير صالØØ© لـ version.txt داخل القالب." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "صيغة غير صالØØ© لـ version.txt داخل القالب. المراجعة ليست معرÙاً صالØاً." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "لا مل٠version.txt تم إيجاده داخل القالب." @@ -2505,10 +2499,6 @@ msgid "Failed:" msgstr "Ùشل:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "لا يمكن كتابة الملÙ." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "التØميل إكتمل." @@ -3685,15 +3675,15 @@ msgid "Show Grid" msgstr "إظهار الشبكة" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "أظهر المساعدات" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "أظهر المساطر" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "أظهر الموجهات" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4520,6 +4510,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4802,10 +4808,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "إلغاء/تÙعيل طي الخط" @@ -4818,6 +4820,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5658,11 +5664,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5922,10 +5923,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5946,7 +5943,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5966,10 +5965,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6657,10 +6652,6 @@ msgstr "مورد Ùرعي" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6770,10 +6761,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "ÙØªØ Ø§Ù„ÙƒÙˆØ¯" @@ -7201,11 +7188,25 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +#, fuzzy +msgid "Next Plane" +msgstr "التبويب التالي" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "Previous Plane" +msgstr "التبويب السابق" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7213,19 +7214,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7326,15 +7327,19 @@ msgstr "تم" #: modules/mono/editor/godotsharp_editor.cpp msgid "Failed to create C# project." -msgstr "Ùشل إنشاء مشروع C#." +msgstr "Ùشل إنشاء مشروع C#‎." #: modules/mono/editor/godotsharp_editor.cpp msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" -msgstr "إنشاء ØÙ„ C#" +msgstr "إنشاء ØÙ„ C#‎" #: modules/mono/editor/mono_bottom_panel.cpp msgid "Builds" @@ -7348,6 +7353,10 @@ msgstr "بناء المشروع" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7851,6 +7860,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8012,6 +8029,15 @@ msgstr "" msgid "Invalid font size." msgstr "" +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "صيغة غير صالØØ© لـ version.txt داخل القالب. المراجعة ليست معرÙاً صالØاً." + +#~ msgid "Can't write file." +#~ msgstr "لا يمكن كتابة الملÙ." + #~ msgid "Next" #~ msgstr "التالي" diff --git a/editor/translations/bg.po b/editor/translations/bg.po index ecef737d82..24b9345051 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -2375,12 +2375,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2435,11 +2429,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -#, fuzzy -msgid "Can't write file." -msgstr "ÐеуÑпешно Ñъздаване на папка." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3629,15 +3618,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4463,6 +4452,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4748,10 +4753,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "Изтриване на анимациÑта?" @@ -4765,6 +4766,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5612,11 +5617,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5882,10 +5882,6 @@ msgid "Please choose an empty folder." msgstr "МолÑ, изнеÑете извън папката на проекта!" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "ВнеÑен проект" @@ -5907,7 +5903,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5928,10 +5926,6 @@ msgid "Rename Project" msgstr "Ðов проект" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6629,10 +6623,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6747,10 +6737,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "Ðова Ñцена" @@ -7196,32 +7182,46 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +#, fuzzy +msgid "Next Plane" +msgstr "Следващ подпрозорец" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "Previous Plane" +msgstr "Предишен подпрозорец" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "Previous Floor" +msgstr "Предишен подпрозорец" + +#: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "Previous Floor" -msgstr "Предишен подпрозорец" +msgid "Grid Map" +msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7335,6 +7335,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7351,6 +7355,10 @@ msgstr "Проект" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7883,6 +7891,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8049,6 +8065,10 @@ msgid "Invalid font size." msgstr "" #, fuzzy +#~ msgid "Can't write file." +#~ msgstr "ÐеуÑпешно Ñъздаване на папка." + +#, fuzzy #~ msgid "Setting '" #~ msgstr "ÐаÑтройки" diff --git a/editor/translations/bn.po b/editor/translations/bn.po index b50fc38439..ff5533e22e 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -2519,13 +2519,6 @@ msgid "Invalid version.txt format inside templates." msgstr "টেমপà§à¦²à§‡à¦Ÿ à¦à¦° version.txt ফরমà§à¦¯à¦¾à¦Ÿ গà§à¦°à¦¹à¦£à¦¯à§‹à¦—à§à¦¯ নয়।" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"টেমপà§à¦²à§‡à¦Ÿ à¦à¦° version.txt ফরমà§à¦¯à¦¾à¦Ÿ অগà§à¦°à¦¹à¦£à¦¯à§‹à¦—à§à¦¯à¥¤ Revision কোন কাংখিত আইডেনà§à¦Ÿà¦¿à¦«à¦¾à§Ÿà¦¾à¦° নয়।" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "টেমপà§à¦²à§‡à¦Ÿà§‡ version.txt খà§à¦à¦œà§‡ পাওয়া যায়নি।" @@ -2585,11 +2578,6 @@ msgstr "বà§à¦¯à¦°à§à¦¥:" #: editor/export_template_manager.cpp #, fuzzy -msgid "Can't write file." -msgstr "টাইলটি খà§à¦à¦œà§‡ পাওয়া যায়নি:" - -#: editor/export_template_manager.cpp -#, fuzzy msgid "Download Complete." msgstr "নীচে" @@ -3839,17 +3827,17 @@ msgstr "গà§à¦°à¦¿à¦¡ দেখান" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy -msgid "Show helpers" +msgid "Show Helpers" msgstr "বোনà§â€Œ/হাড় দেখান" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy -msgid "Show rulers" +msgid "Show Rulers" msgstr "বোনà§â€Œ/হাড় দেখান" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy -msgid "Show guides" +msgid "Show Guides" msgstr "বোনà§â€Œ/হাড় দেখান" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4719,6 +4707,22 @@ msgid "Resource clipboard is empty!" msgstr "রিসোরà§à¦¸à§‡à¦° কà§à¦²à§€à¦ªà¦¬à§‹à¦°à§à¦¡ খালি!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡ খà§à¦²à§à¦¨" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "ধরণ:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "রিসোরà§à¦¸ লোড করà§à¦¨" @@ -5017,10 +5021,6 @@ msgid "Toggle Comment" msgstr "কমেনà§à¦Ÿ টগল করà§à¦¨" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "কà§à¦²à§‹à¦¨ করে নীচে নিন" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "লাইন আনফোলà§à¦¡ করà§à¦¨" @@ -5034,6 +5034,10 @@ msgid "Unfold All Lines" msgstr "সবগà§à¦²à¦¿ লাইন আনফোলà§à¦¡ করà§à¦¨" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "কà§à¦²à§‹à¦¨ করে নীচে নিন" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "সিমà§à¦¬à¦² সমà§à¦ªà§‚রà§à¦£ করà§à¦¨" @@ -5908,11 +5912,6 @@ msgstr "টà§à¦¯à¦¾à¦¬ ২" msgid "Tab 3" msgstr "টà§à¦¯à¦¾à¦¬ ৩" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "ধরণ:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "ডাটার ধরণ:" @@ -6204,10 +6203,6 @@ msgid "Please choose an empty folder." msgstr "অনà§à¦—à§à¦°à¦¹ করে পà§à¦°à¦•à¦²à§à¦ªà§‡à¦° ফোলà§à¦¡à¦¾à¦°à§‡à¦° বাইরে à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨!" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "à¦à¦®à¦¨ à¦à¦•à¦Ÿà¦¿ ফোলà§à¦¡à¦¾à¦° বাছাই করà§à¦¨ যেখানে 'project.godot' নামে কোন ফাইল নেই।" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "পà§à¦°à¦•à¦²à§à¦ª ইমà§à¦ªà§‹à¦°à§à¦Ÿ করা হয়েছে" @@ -6230,7 +6225,9 @@ msgstr "অকারà§à¦¯à¦•à¦° পà§à¦°à¦•à¦²à§à¦ªà§‡à¦° পথ (কোনৠ#: editor/project_manager.cpp #, fuzzy -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "পà§à¦°à¦•à¦²à§à¦ªà§‡à¦° পথে engine.cfg তৈরি করা সমà§à¦à¦¬ হয়নি।" #: editor/project_manager.cpp @@ -6253,11 +6250,6 @@ msgid "Rename Project" msgstr "নামহীন পà§à¦°à¦•à¦²à§à¦ª" #: editor/project_manager.cpp -#, fuzzy -msgid "Couldn't get project.godot in the project path." -msgstr "পà§à¦°à¦•à¦²à§à¦ªà§‡à¦° পথে engine.cfg তৈরি করা সমà§à¦à¦¬ হয়নি।" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "নতà§à¦¨ গেম পà§à¦°à¦•à¦²à§à¦ª" @@ -6992,10 +6984,6 @@ msgstr "রিসোরà§à¦¸à¦¸à¦®à§‚হ:" msgid "Clear Inheritance" msgstr "উতà§à¦¤à¦°à¦¾à¦§à¦¿à¦•à¦¾à¦°à¦¤à§à¦¬ পরিসà§à¦•à¦¾à¦° করà§à¦¨" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡ খà§à¦²à§à¦¨" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "নোড(সমূহ) অপসারণ করà§à¦¨" @@ -7117,10 +7105,6 @@ msgstr "" "গà§à¦°à§à¦ª ডক পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করতে কà§à¦²à¦¿à¦• করà§à¦¨à¥¤" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸:" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "পরবরà§à¦¤à§€ সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿ" @@ -7570,13 +7554,26 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ অপসারণ করà§à¦¨" +msgid "Next Plane" +msgstr "পরের টà§à¦¯à¦¾à¦¬" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ অনà§à¦²à¦¿à¦ªà¦¿ করà§à¦¨" +msgid "Previous Plane" +msgstr "পূরà§à¦¬à§‡à¦° টà§à¦¯à¦¾à¦¬" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "Previous Floor" +msgstr "পূরà§à¦¬à§‡à¦° টà§à¦¯à¦¾à¦¬" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" @@ -7584,22 +7581,23 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Grid Map" -msgstr "গà§à¦°à¦¿à¦¡ সà§à¦¨à§à¦¯à¦¾à¦ª" +msgid "GridMap Delete Selection" +msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ অপসারণ করà§à¦¨" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Snap View" -msgstr "শীরà§à¦· দরà§à¦¶à¦¨" +msgid "GridMap Duplicate Selection" +msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ অনà§à¦²à¦¿à¦ªà¦¿ করà§à¦¨" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Previous Floor" -msgstr "পূরà§à¦¬à§‡à¦° টà§à¦¯à¦¾à¦¬" +msgid "Grid Map" +msgstr "গà§à¦°à¦¿à¦¡ সà§à¦¨à§à¦¯à¦¾à¦ª" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "" +#, fuzzy +msgid "Snap View" +msgstr "শীরà§à¦· দরà§à¦¶à¦¨" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy @@ -7721,6 +7719,10 @@ msgid "Mono" msgstr "মনো" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "পà§à¦°à¦¾à¦¨à§à¦¤à¦°à§‡à¦–া তৈরি করà§à¦¨" @@ -7739,6 +7741,10 @@ msgstr "নতà§à¦¨ পà§à¦°à¦•à¦²à§à¦ª" msgid "Warnings" msgstr "সতরà§à¦•à¦¤à¦¾" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -8301,6 +8307,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp #, fuzzy msgid "Plotting Meshes: " msgstr "ছবিসমূহ বà§à¦²à¦¿à¦Ÿà¦¿à¦‚ (Blitting) করা হচà§à¦›à§‡" @@ -8491,6 +8505,28 @@ msgstr "ফনà§à¦Ÿ তà§à¦²à¦¤à§‡/লোডে সমসà§à¦¯à¦¾ হয়েঠmsgid "Invalid font size." msgstr "ফনà§à¦Ÿà§‡à¦° আকার অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯à¥¤" +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "টেমপà§à¦²à§‡à¦Ÿ à¦à¦° version.txt ফরমà§à¦¯à¦¾à¦Ÿ অগà§à¦°à¦¹à¦£à¦¯à§‹à¦—à§à¦¯à¥¤ Revision কোন কাংখিত আইডেনà§à¦Ÿà¦¿à¦«à¦¾à§Ÿà¦¾à¦° " +#~ "নয়।" + +#, fuzzy +#~ msgid "Can't write file." +#~ msgstr "টাইলটি খà§à¦à¦œà§‡ পাওয়া যায়নি:" + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "à¦à¦®à¦¨ à¦à¦•à¦Ÿà¦¿ ফোলà§à¦¡à¦¾à¦° বাছাই করà§à¦¨ যেখানে 'project.godot' নামে কোন ফাইল নেই।" + +#, fuzzy +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "পà§à¦°à¦•à¦²à§à¦ªà§‡à¦° পথে engine.cfg তৈরি করা সমà§à¦à¦¬ হয়নি।" + +#, fuzzy +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "পà§à¦°à¦•à¦²à§à¦ªà§‡à¦° পথে engine.cfg তৈরি করা সমà§à¦à¦¬ হয়নি।" + #~ msgid "Next" #~ msgstr "পরবরà§à¦¤à§€" diff --git a/editor/translations/ca.po b/editor/translations/ca.po index 91d1d55e64..5af9d98ec6 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-01-24 02:50+0000\n" +"PO-Revision-Date: 2018-02-27 02:34+0000\n" "Last-Translator: Roger Blanco Ribera <roger.blancoribera@gmail.com>\n" "Language-Team: Catalan <https://hosted.weblate.org/projects/godot-engine/" "godot/ca/>\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -2455,14 +2455,6 @@ msgid "Invalid version.txt format inside templates." msgstr "El format de version.txt dins de les plantilles no és và lid." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"El format de version.txt dins les plantilles no és và lid. \"Revision\" no és " -"un indentificador và lid." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "No s'ha trobat cap version.txt dins les plantilles." @@ -2517,10 +2509,6 @@ msgid "Failed:" msgstr "Ha fallat:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "No es pot escriure el fitxer." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Baixada Completa." @@ -3702,15 +3690,15 @@ msgid "Show Grid" msgstr "Mostra la graella" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Mostrar els Ajudants" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Mostra els regles" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Mostra les guies" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -3984,7 +3972,7 @@ msgstr "La Malla continguda no és del tipus ArrayMesh." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Unwrap failed, mesh may not be manifold?" -msgstr "No s'han pogut desembolcar les UV. Comproveu la topologia de la malla" +msgstr "No s'han pogut desembolcar les UV. Comproveu la topologia de la malla." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "No mesh to debug." @@ -4537,6 +4525,22 @@ msgid "Resource clipboard is empty!" msgstr "El porta-retalls de Recursos és buit!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Obre en l'Editor" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Instà ncia:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Tipus:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Carrega un Recurs" @@ -4823,10 +4827,6 @@ msgid "Toggle Comment" msgstr "Comentaris" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Clona avall" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "(Des)Plega la lÃnia" @@ -4839,6 +4839,10 @@ msgid "Unfold All Lines" msgstr "Desplega totes les LÃnies" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Clona avall" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "Completa el SÃmbol" @@ -5682,11 +5686,6 @@ msgstr "Pestanya 2" msgid "Tab 3" msgstr "Pestanya 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Tipus:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Tipus de Dades:" @@ -5955,11 +5954,6 @@ msgid "Please choose an empty folder." msgstr "Selecciona un directori buit." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" -"Seleccioneu un directori que no contingui ja un fitxer 'project.godot'." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Project importat" @@ -5980,8 +5974,12 @@ msgid "Invalid project path (changed anything?)." msgstr "El Camà del Projecte no és và lid (S'ha produit algun canvi?)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "No s'ha trobat el fitxer 'project.godot' en el camà del Projecte." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" +"No es pot carregar el fitxer 'project.godot' en el camà del projecte (error " +"%d). Pot ser que falti o que estigui malmès." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -6000,10 +5998,6 @@ msgid "Rename Project" msgstr "Reanomena el Projecte" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "No es pot trobat el el fitxer 'project.godot' en el camà del projecte." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Nou Projecte de Joc" @@ -6706,10 +6700,6 @@ msgstr "Sub-Recursos" msgid "Clear Inheritance" msgstr "Elimina l'Herència" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Obre en l'Editor" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Elimina els Nodes" @@ -6827,10 +6817,6 @@ msgstr "" "Clic per mostrar el Tauler de Grups." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "Instà ncia:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Obre un Script" @@ -7261,32 +7247,44 @@ msgid "Object can't provide a length." msgstr "L'objecte no pot proporcionar una longitud." #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "Elimina la Selecció del GridMap" +msgid "Next Plane" +msgstr "Pla següent" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "Duplica la Selecció del GridMap" +msgid "Previous Plane" +msgstr "Pla anterior" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "Pla:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "Planta Següent" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Planta Anterior" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "Planta:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "Mapa de Graella" +msgid "GridMap Delete Selection" +msgstr "Elimina la Selecció del GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "Alinea la Vista" +msgid "GridMap Duplicate Selection" +msgstr "Duplica la Selecció del GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "Planta Anterior" +msgid "Grid Map" +msgstr "Mapa de Graella" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "Planta Següent" +msgid "Snap View" +msgstr "Alinea la Vista" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7393,6 +7391,10 @@ msgid "Mono" msgstr "Mono" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "Sobre el suport de C#" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "Crea una solució en C#" @@ -7408,6 +7410,10 @@ msgstr "Munta el Projecte" msgid "Warnings" msgstr "Avisos" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7960,6 +7966,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "El node ARVROrigin requreix un node Fill del tipus ARVRCamera" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "%d%%" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "(Temps restant: %d:%02d s)" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "S'està n traçant les Malles: " @@ -8159,6 +8173,27 @@ msgstr "Error carregant lletra." msgid "Invalid font size." msgstr "La mida de la lletra no és và lida." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "El format de version.txt dins les plantilles no és và lid. \"Revision\" no " +#~ "és un indentificador và lid." + +#~ msgid "Can't write file." +#~ msgstr "No es pot escriure el fitxer." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "" +#~ "Seleccioneu un directori que no contingui ja un fitxer 'project.godot'." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "No s'ha trobat el fitxer 'project.godot' en el camà del Projecte." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "" +#~ "No es pot trobat el el fitxer 'project.godot' en el camà del projecte." + #~ msgid "Next" #~ msgstr "Següent" diff --git a/editor/translations/cs.po b/editor/translations/cs.po index ce645b139b..aa29f16038 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -2428,13 +2428,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Neplatný formát version.txt uvnitÅ™ Å¡ablon." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Neplatný formát version.txt uvnitÅ™ Å¡ablon. Revize nenà platný identifikátor." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Nenalezena version.txt uvnitÅ™ Å¡ablon." @@ -2487,10 +2480,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Nelze zapsat soubor." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3670,15 +3659,15 @@ msgstr "Zobrazit mřÞku" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy -msgid "Show helpers" +msgid "Show Helpers" msgstr "Zobrazit pomocné" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Zobrazit pravÃtka" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Zobrazit vodÃtka" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4514,6 +4503,22 @@ msgid "Resource clipboard is empty!" msgstr "Schránka zdroje je prázdná!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "NaÄÃst zdroj" @@ -4801,10 +4806,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "Běž na řádek" @@ -4818,6 +4819,10 @@ msgid "Unfold All Lines" msgstr "Rozložit vÅ¡echny řádky" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5665,11 +5670,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5936,10 +5936,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5960,7 +5956,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5980,10 +5978,6 @@ msgid "Rename Project" msgstr "PÅ™ejmenovat projekt" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6676,10 +6670,6 @@ msgstr "DÃlÄà zdroje" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6792,10 +6782,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "OtevÅ™Ãt skript" @@ -7225,32 +7211,46 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "Smazat vybraný" +msgid "Next Plane" +msgstr "DalÅ¡Ã záložka" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "Duplikovat výbÄ›r" +msgid "Previous Plane" +msgstr "PÅ™edchozà záložka" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Delete Selection" +msgstr "Smazat vybraný" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "GridMap Duplicate Selection" +msgstr "Duplikovat výbÄ›r" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7364,6 +7364,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "VytvoÅ™it C# Å™eÅ¡enÃ" @@ -7380,6 +7384,10 @@ msgstr "Sestavit projekt" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp #, fuzzy msgid "" @@ -7924,6 +7932,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8114,6 +8130,16 @@ msgstr "Chyba nahrávánà fontu." msgid "Invalid font size." msgstr "Neplatná velikost fontu." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Neplatný formát version.txt uvnitÅ™ Å¡ablon. Revize nenà platný " +#~ "identifikátor." + +#~ msgid "Can't write file." +#~ msgstr "Nelze zapsat soubor." + #~ msgid "Next" #~ msgstr "DalÅ¡Ã" diff --git a/editor/translations/da.po b/editor/translations/da.po index 786cabcbdc..ca47dc00e1 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -2485,14 +2485,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Ugyldigt version.txt format inde i skabeloner." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Ugyldigt version.txt format inde i skabeloner. Revision er ikke en gyldig " -"identifikator." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Ingen version.txt fundet inde i skabeloner." @@ -2550,10 +2542,6 @@ msgid "Failed:" msgstr "Fejlet:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Kan ikke skrive til fil." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Download fuldført." @@ -3742,15 +3730,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4581,6 +4569,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4866,10 +4870,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "Fold Line" @@ -4883,6 +4883,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5725,11 +5729,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5991,10 +5990,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -6016,7 +6011,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -6036,10 +6033,6 @@ msgid "Rename Project" msgstr "Omdøb Projekt" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6733,10 +6726,6 @@ msgstr "Sub-Ressourcer:" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6847,10 +6836,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Ã…ben script" @@ -7277,31 +7262,45 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "GridMap Slet Markerede" +msgid "Next Plane" +msgstr "Næste fane" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "GridMap Duplikér Markerede" +#, fuzzy +msgid "Previous Plane" +msgstr "Forrige fane" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Delete Selection" +msgstr "GridMap Slet Markerede" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Duplicate Selection" +msgstr "GridMap Duplikér Markerede" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7412,6 +7411,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "Opret Abonnement" @@ -7429,6 +7432,10 @@ msgstr "Projekt" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7969,6 +7976,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8154,6 +8169,16 @@ msgstr "Error loading skrifttype." msgid "Invalid font size." msgstr "Ugyldig skriftstørrelse." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Ugyldigt version.txt format inde i skabeloner. Revision er ikke en gyldig " +#~ "identifikator." + +#~ msgid "Can't write file." +#~ msgstr "Kan ikke skrive til fil." + #~ msgid "Next" #~ msgstr "Næste" diff --git a/editor/translations/de.po b/editor/translations/de.po index d0fa1597a5..87f69c3fde 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -28,7 +28,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-01-22 08:08+0000\n" +"PO-Revision-Date: 2018-02-12 08:36+0000\n" "Last-Translator: So Wieso <sowieso@dukun.de>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot/de/>\n" @@ -53,11 +53,11 @@ msgstr "Schlüsselbildzeit ändern" #: editor/animation_editor.cpp msgid "Anim Change Transition" -msgstr "Ãœbergang beim Animationswechsel" +msgstr "Ãœbergang bearbeiten" #: editor/animation_editor.cpp msgid "Anim Change Transform" -msgstr "Transformation ändern" +msgstr "Transformation bearbeiten" #: editor/animation_editor.cpp msgid "Anim Change Keyframe Value" @@ -207,11 +207,11 @@ msgstr "Animation bereinigen" #: editor/animation_editor.cpp msgid "Create NEW track for %s and insert key?" -msgstr "NEUE Spur für %s erstellenund Schlüsselbild hinzufügen?" +msgstr "NEUE Spur für %s erstellen und Schlüsselbild hinzufügen?" #: editor/animation_editor.cpp msgid "Create %d NEW tracks and insert keys?" -msgstr "%d NEUE Spuren erstelleb und Schlüsselbilder hinzufügen?" +msgstr "%d NEUE Spuren erstellen und Schlüsselbilder hinzufügen?" #: editor/animation_editor.cpp editor/create_dialog.cpp #: editor/editor_audio_buses.cpp editor/plugins/abstract_polygon_2d_editor.cpp @@ -267,11 +267,11 @@ msgstr "Länge (s):" #: editor/animation_editor.cpp msgid "Animation length (in seconds)." -msgstr "Animationslänge (in Sekunden)." +msgstr "Animationsdauer (in Sekunden)." #: editor/animation_editor.cpp msgid "Step (s):" -msgstr "Schritte (s):" +msgstr "Schrittweite (s):" #: editor/animation_editor.cpp msgid "Cursor step snap (in seconds)." @@ -279,7 +279,7 @@ msgstr "Cursor Schrittraster (in Sekunden)." #: editor/animation_editor.cpp msgid "Enable/Disable looping in animation." -msgstr "Animationswiederholung aktivieren/deaktivieren." +msgstr "Animationsschleife aktivieren/deaktivieren." #: editor/animation_editor.cpp msgid "Add new tracks." @@ -344,7 +344,7 @@ msgstr "Skalierungsverhältnis:" #: editor/animation_editor.cpp msgid "Call Functions in Which Node?" -msgstr "In welcher Node sollen die Funktionen aufgerufen werden?" +msgstr "Node dessen Funktionen aufgerufen werden sollen auswählen." #: editor/animation_editor.cpp msgid "Remove invalid keys" @@ -360,7 +360,7 @@ msgstr "Alle Animationen bereinigen" #: editor/animation_editor.cpp msgid "Clean-Up Animation(s) (NO UNDO!)" -msgstr "Alle Animationen bereinigen (Kann nicht rückgängig gemacht werden!)" +msgstr "Animationen bereinigen (Kann nicht rückgängig gemacht werden!)" #: editor/animation_editor.cpp msgid "Clean-Up" @@ -507,7 +507,7 @@ msgstr "Verbinden" #: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" -msgstr "Verbinde '%s' zu '%s'" +msgstr "Verbinde ‚%s‘ mit ‚%s‘" #: editor/connections_dialog.cpp msgid "Connecting Signal:" @@ -577,23 +577,23 @@ msgstr "Suche Ersatz für:" #: editor/dependency_editor.cpp msgid "Dependencies For:" -msgstr "Abhängigkeiten Für:" +msgstr "Abhängigkeiten für:" #: editor/dependency_editor.cpp msgid "" "Scene '%s' is currently being edited.\n" "Changes will not take effect unless reloaded." msgstr "" -"Die Szene '%s' wird momentan bearbeitet.\n" -"Änderungen werden nicht angezeigt bis die Szene neu geladen wird." +"Die Szene ‚%s‘ wird momentan bearbeitet.\n" +"Änderungen werden erst wirksam, wenn die Szene neu geladen wird." #: editor/dependency_editor.cpp msgid "" "Resource '%s' is in use.\n" "Changes will take effect when reloaded." msgstr "" -"Die Ressource '%s' wird momentan benutzt.\n" -"Änderungen werden erst nach Neuladen der Ressource aktiv." +"Die Ressource ‚%s‘ wird momentan benutzt.\n" +"Änderungen werden erst durch Neuladen wirksam." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -624,7 +624,7 @@ msgstr "Abhängigkeiteneditor" #: editor/dependency_editor.cpp msgid "Search Replacement Resource:" -msgstr "Ersatz-Ressource suchen:" +msgstr "Ersatzressource suchen:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help.cpp editor/editor_node.cpp editor/filesystem_dock.cpp @@ -649,8 +649,8 @@ msgid "" "work.\n" "Remove them anyway? (no undo)" msgstr "" -"Die zu entfernenden Dateien werden von anderen Ressourcen gebraucht, damit " -"sie richtig funktionieren können.\n" +"Andere Ressourcen benötigen die zu entfernenden Dateien, um richtig zu " +"funktionieren.\n" "Trotzdem entfernen? (Kann nicht rückgängig gemacht werden)" #: editor/dependency_editor.cpp @@ -721,7 +721,7 @@ msgstr "Wörterbuchwert ändern" #: editor/editor_about.cpp msgid "Thanks from the Godot community!" -msgstr "Danke von der Godot-Community!" +msgstr "Die Godot-Gemeinschaft bedankt sich!" #: editor/editor_about.cpp msgid "Thanks!" @@ -741,7 +741,7 @@ msgstr "Hauptentwickler" #: editor/editor_about.cpp msgid "Project Manager " -msgstr "Projektverwalter " +msgstr "Projektverwaltung " #: editor/editor_about.cpp msgid "Developers" @@ -753,27 +753,27 @@ msgstr "Autoren" #: editor/editor_about.cpp msgid "Platinum Sponsors" -msgstr "Platinum Sponsoren" +msgstr "Platin-Sponsoren" #: editor/editor_about.cpp msgid "Gold Sponsors" -msgstr "Gold Sponsoren" +msgstr "Gold-Sponsoren" #: editor/editor_about.cpp msgid "Mini Sponsors" -msgstr "Mini Sponsoren" +msgstr "Mini-Sponsoren" #: editor/editor_about.cpp msgid "Gold Donors" -msgstr "Gold Unterstützer" +msgstr "Gold-Unterstützer" #: editor/editor_about.cpp msgid "Silver Donors" -msgstr "Silver Unterstützer" +msgstr "Silber-Unterstützer" #: editor/editor_about.cpp msgid "Bronze Donors" -msgstr "Bronze Unterstützer" +msgstr "Bronze-Unterstützer" #: editor/editor_about.cpp msgid "Donors" @@ -794,10 +794,10 @@ msgid "" "is an exhaustive list of all such thirdparty components with their " "respective copyright statements and license terms." msgstr "" -"Die Godot-Engine baut auf einer Vielzahl freier und quelloffener projekt-" -"externer Bibliotheken auf, die alle kompatibel mit den Auflagen der MIT-" -"Lizenz sind. Es folgt eine vollständige Liste aller verwendeten externen " -"Bibliotheken mit den jeweiligen zugehörigen Urheberrechtserklärungen und " +"Die Godot-Engine baut auf vielen freien und quelloffenen Bibliotheken von " +"Drittanbietern auf, welche alle mit der MIT-Lizenz konform sind. Es folgt " +"eine vollständige Liste aller verwendeten Bibliotheken von Drittanbietern " +"mit den jeweiligen zugehörigen Urheberrechtserklärungen und " "Lizenzbedingungen." #: editor/editor_about.cpp @@ -836,7 +836,7 @@ msgstr "Installieren" #: editor/editor_asset_installer.cpp msgid "Package Installer" -msgstr "Paketinstaller" +msgstr "Erweiterungenverwaltung" #: editor/editor_audio_buses.cpp msgid "Speakers" @@ -844,7 +844,7 @@ msgstr "Lautsprecher" #: editor/editor_audio_buses.cpp msgid "Add Effect" -msgstr "Audiobuseffekt hinzufügen" +msgstr "Effekt hinzufügen" #: editor/editor_audio_buses.cpp msgid "Rename Audio Bus" @@ -868,7 +868,7 @@ msgstr "Audiobus Bypasseffekte umschalten" #: editor/editor_audio_buses.cpp msgid "Select Audio Bus Send" -msgstr "Audiobus Senden auswählen" +msgstr "Audiobus senden auswählen" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus Effect" @@ -983,7 +983,7 @@ msgstr "Lade ein existierendes Bus-Layout." #: editor/editor_audio_buses.cpp #: editor/plugins/animation_player_editor_plugin.cpp msgid "Save As" -msgstr "Speichern als" +msgstr "Speichern unter" #: editor/editor_audio_buses.cpp msgid "Save this Bus Layout to a file." @@ -995,7 +995,7 @@ msgstr "Standard laden" #: editor/editor_audio_buses.cpp msgid "Load the default Bus Layout." -msgstr "Standart Bus Layout laden." +msgstr "Standard Bus-Layout laden." #: editor/editor_autoload_settings.cpp msgid "Invalid name." @@ -1364,8 +1364,9 @@ msgid "" "$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/" "url][/color]." msgstr "" -"Es gibt zurzeit keine Tutorials zu dieser Klasse. [color=$color][url=" -"$url]Ergänzungen durch eigene Beiträge[/url][/color] sind sehr erwünscht!" +"Es gibt zurzeit keine Tutorials zu dieser Klasse. Mitwirkungen durch [color=" +"$color][url=$url]eigene Beiträge[/url][/color] oder [color=$color][url=" +"$url2]Meldung von Problemen[/url][/color] sind sehr erwünscht." #: editor/editor_help.cpp msgid "Properties" @@ -2485,14 +2486,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Ungültiges version.txt-Format in Templates." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Ungültiges version.txt-Format in Templates. Revision ist kein gültiger " -"Bezeichner." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Keine version.txt in Templates gefunden." @@ -2547,10 +2540,6 @@ msgid "Failed:" msgstr "Fehlgeschlagen:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Konnte Datei nicht schreiben." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Download abgeschlossen." @@ -2909,7 +2898,7 @@ msgstr "Gruppen" #: editor/node_dock.cpp msgid "Select a Node to edit Signals and Groups." -msgstr "Wähle ein Node um Signale und Gruppen zu bearbeiten." +msgstr "Node auswählen um Signale und Gruppen zu bearbeiten." #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -3738,15 +3727,15 @@ msgid "Show Grid" msgstr "Raster anzeigen" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Helfer anzeigen" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Lineale anzeigen" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Hilfslinien anzeigen" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4577,6 +4566,22 @@ msgid "Resource clipboard is empty!" msgstr "Zwischenablage für Ressourcen ist leer!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Im Editor öffnen" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Instanz:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Typ:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Ressource laden" @@ -4863,10 +4868,6 @@ msgid "Toggle Comment" msgstr "Kommentar umschalten" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Klone herunter" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "Zeile ein/aufklappen" @@ -4879,6 +4880,10 @@ msgid "Unfold All Lines" msgstr "Alle Zeilen aufklappen" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Klone herunter" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "Symbol vervollständigen" @@ -5722,11 +5727,6 @@ msgstr "Tab 2" msgid "Tab 3" msgstr "Tab 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Typ:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Datentyp:" @@ -5994,10 +5994,6 @@ msgid "Please choose an empty folder." msgstr "Bitte einen leeren Ordner auswählen." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "Ein Ordner ohne ‚project.godot‘-Datei muss ausgewählt werden." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Importiertes Projekt" @@ -6019,8 +6015,11 @@ msgid "Invalid project path (changed anything?)." msgstr "Ungültiger Projektpfad (etwas geändert?)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "project.godot konnte nicht im Projektpfad gefunden werden." +#, fuzzy +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "project.godot des Projektpfads konnte nicht bearbeitet werden." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -6039,10 +6038,6 @@ msgid "Rename Project" msgstr "Projekt umbenennen" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "project.godot konnte nicht im Projektpfad gefunden werden." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Neues Spiel" @@ -6750,10 +6745,6 @@ msgstr "Unter-Ressourcen" msgid "Clear Inheritance" msgstr "Leere Vererbung" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Im Editor öffnen" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Node(s) löschen" @@ -6871,10 +6862,6 @@ msgstr "" "Hier klicken zur Gruppenverwaltung." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "Instanz:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Skript öffnen" @@ -6917,7 +6904,7 @@ msgstr "Node-Konfigurationswarnung!" #: editor/scene_tree_editor.cpp msgid "Select a Node" -msgstr "Wähle ein Node" +msgstr "Node auswählen" #: editor/script_create_dialog.cpp msgid "Error loading template '%s'" @@ -7306,32 +7293,46 @@ msgid "Object can't provide a length." msgstr "Objekt kann keine Länge vorweisen." #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "GridMap-Auswahl löschen" +#, fuzzy +msgid "Next Plane" +msgstr "Nächster Tab" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "GridMap-Auswahl duplizieren" +#, fuzzy +msgid "Previous Plane" +msgstr "Vorheriger Tab" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "Nächste Ebene" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Vorherige Ebene" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "Ebene:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "Gitterkarte" +msgid "GridMap Delete Selection" +msgstr "GridMap-Auswahl löschen" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "Sicht einrasten" +msgid "GridMap Duplicate Selection" +msgstr "GridMap-Auswahl duplizieren" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "Vorherige Ebene" +msgid "Grid Map" +msgstr "Gitterkarte" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "Nächste Ebene" +msgid "Snap View" +msgstr "Sicht einrasten" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7438,6 +7439,10 @@ msgid "Mono" msgstr "Mono" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "Erzeuge C#-Lösung" @@ -7453,6 +7458,10 @@ msgstr "Projekt bauen" msgid "Warnings" msgstr "Warnungen" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -8017,6 +8026,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin benötigt ein ARVRCamera-Unterobjekt" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "Plotte Meshe: " @@ -8222,6 +8239,25 @@ msgstr "Fehler beim Laden der Schriftart." msgid "Invalid font size." msgstr "Ungültige Schriftgröße." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Ungültiges version.txt-Format in Templates. Revision ist kein gültiger " +#~ "Bezeichner." + +#~ msgid "Can't write file." +#~ msgstr "Konnte Datei nicht schreiben." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "Ein Ordner ohne ‚project.godot‘-Datei muss ausgewählt werden." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "project.godot konnte nicht im Projektpfad gefunden werden." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "project.godot konnte nicht im Projektpfad gefunden werden." + #~ msgid "Next" #~ msgstr "Nächste" diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po index e0d10c9264..a9b1b8a994 100644 --- a/editor/translations/de_CH.po +++ b/editor/translations/de_CH.po @@ -2398,12 +2398,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2457,11 +2451,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -#, fuzzy -msgid "Can't write file." -msgstr "Neues Projekt erstellen" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3662,15 +3651,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4510,6 +4499,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4793,10 +4798,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "Bild einfügen" @@ -4810,6 +4811,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5661,11 +5666,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5932,10 +5932,6 @@ msgid "Please choose an empty folder." msgstr "Bitte ausserhalb des Projekt Verzeichnis exportieren!" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Importierte Projekte" @@ -5958,7 +5954,9 @@ msgstr "Ungültiger Projektpfad, (wurde was geändert?)!" #: editor/project_manager.cpp #, fuzzy -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "Die engine.cfg kann im Projektverzeichnis nicht erstellt werden." #: editor/project_manager.cpp @@ -5981,11 +5979,6 @@ msgid "Rename Project" msgstr "Neues Projekt erstellen" #: editor/project_manager.cpp -#, fuzzy -msgid "Couldn't get project.godot in the project path." -msgstr "Die engine.cfg kann im Projektverzeichnis nicht erstellt werden." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6690,10 +6683,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Node(s) löschen" @@ -6808,10 +6797,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "Script hinzufügen" @@ -7244,11 +7229,23 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +msgid "Next Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7256,19 +7253,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7380,6 +7377,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7396,6 +7397,10 @@ msgstr "Projektname:" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7940,6 +7945,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8105,6 +8118,18 @@ msgstr "" msgid "Invalid font size." msgstr "" +#, fuzzy +#~ msgid "Can't write file." +#~ msgstr "Neues Projekt erstellen" + +#, fuzzy +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "Die engine.cfg kann im Projektverzeichnis nicht erstellt werden." + +#, fuzzy +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "Die engine.cfg kann im Projektverzeichnis nicht erstellt werden." + #~ msgid "Move Add Key" #~ msgstr "Bild bewegen/einfügen" diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index a1e1b1d4ae..7a13a5bcc8 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -2357,12 +2357,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2415,10 +2409,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3581,15 +3571,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4412,6 +4402,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4694,10 +4700,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "" @@ -4710,6 +4712,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5550,11 +5556,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5814,10 +5815,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5838,7 +5835,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5858,10 +5857,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6549,10 +6544,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6662,10 +6653,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7088,11 +7075,23 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +msgid "Next Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7100,19 +7099,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7220,6 +7219,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7235,6 +7238,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7734,6 +7741,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/editor/translations/el.po b/editor/translations/el.po index e8841a9338..6eea5da60d 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-01-24 19:46+0000\n" +"PO-Revision-Date: 2018-02-27 22:19+0000\n" "Last-Translator: George Tsiamasiotis <gtsiam@windowslive.com>\n" "Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/" "el/>\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -2460,14 +2460,6 @@ msgid "Invalid version.txt format inside templates." msgstr "ΆκυÏη μοÏφή version.txt μÎσα στα Ï€Ïότυπα." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"ΆκυÏη μοÏφή version.txt μÎσα στα Ï€Ïότυπα. Το Revision δεν είναι ÎγκυÏο " -"αναγνωÏιστικό." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Δεν βÏÎθηκε version.txt μÎσα στα Ï€Ïότυπα." @@ -2522,10 +2514,6 @@ msgid "Failed:" msgstr "ΑπÎτυχε:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Δεν ήταν δυνατή η εγγÏαφή στο αÏχείο." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Η λήψη ολοκληÏώθηκε." @@ -3716,15 +3704,15 @@ msgid "Show Grid" msgstr "Εμφάνιση πλÎγματος" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Εμφάνιση βοηθών" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Εμφάνιση χαÏάκων" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Εμφάνιση οδηγών" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4555,6 +4543,22 @@ msgid "Resource clipboard is empty!" msgstr "Το Ï€ÏόχειÏο πόÏων είναι άδειο!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Άνοιγμα στον επεξεÏγαστή" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Στιγμιότυπο:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "ΤÏπος:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "ΦόÏτωση πόÏου" @@ -4841,10 +4845,6 @@ msgid "Toggle Comment" msgstr "Εναλλαγή σχολιασμοÏ" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Κλωνοποίηση κάτω" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "Δίπλωμα/Ξεδίπλωμα γÏαμμής" @@ -4857,6 +4857,10 @@ msgid "Unfold All Lines" msgstr "Ξεδίπλωμα όλων των γÏαμμών" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Κλωνοποίηση κάτω" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "ΣυμπλήÏωση συμβόλου" @@ -5702,11 +5706,6 @@ msgstr "ΚαÏÏ„Îλα 2" msgid "Tab 3" msgstr "ΚαÏÏ„Îλα 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "ΤÏπος:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "ΤÏπος δεδομÎνων:" @@ -5976,11 +5975,6 @@ msgid "Please choose an empty folder." msgstr "ΠαÏακαλοÏμε επιλÎξτε Îναν άδειο φάκελο." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" -"ΠαÏακαλοÏμε επιλÎξτε Îναν φάκελο που δεν πεÏιÎχει Îνα αÏχείο 'project.godot'." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "ΕισαγμÎνο ÎÏγο" @@ -6001,8 +5995,12 @@ msgid "Invalid project path (changed anything?)." msgstr "Μη ÎγκυÏη διαδÏομή ÎÏγου (Αλλάξατε τίποτα;)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "Δεν βÏÎθηκε το project.godot στη διαδÏομή του ÎÏγου." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" +"ΑδÏνατη η φόÏτωση του project.godot (σφάλμα %d). ΜποÏεί να λείπει ή να είναι " +"κατεστÏαμÎνο." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -6022,10 +6020,6 @@ msgid "Rename Project" msgstr "Μετονομασία ÎÏγου" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "Δεν βÏÎθηκε το project.godot στη διαδÏομή του ÎÏγου." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "ÎÎο ÎÏγο παιχνιδιοÏ" @@ -6736,10 +6730,6 @@ msgstr "Yπο-Î ÏŒÏοι" msgid "Clear Inheritance" msgstr "ΕκκαθάÏιση κληÏονομικότητας" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Άνοιγμα στον επεξεÏγαστή" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "ΔιαγÏαφή Κόμβων" @@ -6857,10 +6847,6 @@ msgstr "" "Πατήστε για να δείξετε την πλατφόÏμα σημάτων." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "Στιγμιότυπο:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Άνοιγμα δεσμής ενεÏγειών" @@ -7293,32 +7279,44 @@ msgid "Object can't provide a length." msgstr "Το αντικείμενο δεν Îχει μήκος." #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "GridMap ΔιαγÏαφή επιλογής" +msgid "Next Plane" +msgstr "Επόμενο επίπεδο" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "GridMap Διπλασιασμός επιλογής" +msgid "Previous Plane" +msgstr "Î ÏοηγοÏμενο επίπεδο" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "Επίπεδο:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "Επόμενο πάτωμα" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Î ÏοηγοÏμενο πάτωμα" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "Δάπεδο:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "ΧάÏτης δικτÏου" +msgid "GridMap Delete Selection" +msgstr "GridMap ΔιαγÏαφή επιλογής" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "ΚοÏμπωμα όψης" +msgid "GridMap Duplicate Selection" +msgstr "GridMap Διπλασιασμός επιλογής" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "Î ÏοηγοÏμενο πάτωμα" +msgid "Grid Map" +msgstr "ΧάÏτης δικτÏου" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "Επόμενο πάτωμα" +msgid "Snap View" +msgstr "ΚοÏμπωμα όψης" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7425,6 +7423,10 @@ msgid "Mono" msgstr "Μονοφωνικό" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "Σχετικά με την υποστήÏιξη C#" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "ΔημιουÏγία λÏσης C#" @@ -7440,6 +7442,10 @@ msgstr "Δόμηση ÎÏγου" msgid "Warnings" msgstr "Î Ïοειδοποιήσεις" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7998,6 +8004,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "Το ARVROrigin απαιτεί Îναν κόμβο ARVRCamera ως παιδί" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "%d%%" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "(ΟλοκλήÏωση σε: %d:%02d s)" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "ΤοποθÎτηση πλεγμάτων: " @@ -8202,6 +8216,27 @@ msgstr "Σφάλμα κατά την φόÏτωση της γÏαμματοσεΠmsgid "Invalid font size." msgstr "Μη ÎγκυÏο μÎγεθος γÏαμματοσειÏάς." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "ΆκυÏη μοÏφή version.txt μÎσα στα Ï€Ïότυπα. Το Revision δεν είναι ÎγκυÏο " +#~ "αναγνωÏιστικό." + +#~ msgid "Can't write file." +#~ msgstr "Δεν ήταν δυνατή η εγγÏαφή στο αÏχείο." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "" +#~ "ΠαÏακαλοÏμε επιλÎξτε Îναν φάκελο που δεν πεÏιÎχει Îνα αÏχείο 'project." +#~ "godot'." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "Δεν βÏÎθηκε το project.godot στη διαδÏομή του ÎÏγου." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "Δεν βÏÎθηκε το project.godot στη διαδÏομή του ÎÏγου." + #~ msgid "Next" #~ msgstr "Επόμενο" diff --git a/editor/translations/es.po b/editor/translations/es.po index df1a38d45b..b9b342114c 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -8,26 +8,29 @@ # Alejandro Alvarez <eliluminado00@gmail.com>, 2017. # BLaDoM GUY <simplybladom@gmail.com>, 2017. # Carlos López <genetita@gmail.com>, 2016. +# David Arranz <davarrcal@hotmail.com>, 2018. # David Couto <davidcouto@gmail.com>, 2017. # Dharkael <izhe@hotmail.es>, 2017. # Diego López <diegodario21@gmail.com>, 2017. -# Gustavo Leon <gleondiaz@gmail.com>, 2017. +# Gustavo Leon <gleondiaz@gmail.com>, 2017-2018. # Juan Quiroga <juanquiroga9@gmail.com>, 2017. # Kiji Pixel <raccoon.fella@gmail.com>, 2017. # Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2017. -# Lonsfor <lotharw@protonmail.com>, 2017. -# Oscar Carballal <oscar.carballal@protonmail.com>, 2017. +# Lonsfor <lotharw@protonmail.com>, 2017-2018. +# Mario Nachbaur <manachbaur@gmail.com>, 2018. +# Oscar Carballal <oscar.carballal@protonmail.com>, 2017-2018. # Rabid Orange <theorangerabid@gmail.com>, 2017. -# Roger Blanco Ribera <roger.blancoribera@gmail.com>, 2016-2017. +# Roger Blanco Ribera <roger.blancoribera@gmail.com>, 2016-2018. # Sebastian Silva <sebastian@fuentelibre.org>, 2016. # Swyter <swyterzone@gmail.com>, 2016-2017. +# Vazquinhos <vazquinhos@gmail.com>, 2018. # msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2017-12-09 22:50+0000\n" -"Last-Translator: Aleix Sanchis <aleixsanchis@hotmail.com>\n" +"PO-Revision-Date: 2018-03-03 09:49+0000\n" +"Last-Translator: David Arranz <davarrcal@hotmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" "Language: es\n" @@ -35,7 +38,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2.18-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -46,9 +49,8 @@ msgid "All Selection" msgstr "Toda la selección" #: editor/animation_editor.cpp -#, fuzzy msgid "Anim Change Keyframe Time" -msgstr "Cambiar valor de animación" +msgstr "Cambiar el tiempo de la clave de animación" #: editor/animation_editor.cpp msgid "Anim Change Transition" @@ -59,9 +61,8 @@ msgid "Anim Change Transform" msgstr "Cambiar transformación de animación" #: editor/animation_editor.cpp -#, fuzzy msgid "Anim Change Keyframe Value" -msgstr "Cambiar valor de animación" +msgstr "Cambiar valor de la clave de animación" #: editor/animation_editor.cpp msgid "Anim Change Call" @@ -178,9 +179,8 @@ msgid "Constant" msgstr "Constante" #: editor/animation_editor.cpp -#, fuzzy msgid "In" -msgstr "In" +msgstr "Entrada" #: editor/animation_editor.cpp msgid "Out" @@ -276,7 +276,7 @@ msgstr "Paso (s):" #: editor/animation_editor.cpp msgid "Cursor step snap (in seconds)." -msgstr "Fijado de cursor por pasos (en segundos)." +msgstr "Fijado del cursor por pasos (en segundos)." #: editor/animation_editor.cpp msgid "Enable/Disable looping in animation." @@ -288,7 +288,7 @@ msgstr "Añadir Nuevas Pistas." #: editor/animation_editor.cpp msgid "Move current track up." -msgstr "Subir la pasta actual." +msgstr "Subir la pista actual." #: editor/animation_editor.cpp msgid "Move current track down." @@ -390,7 +390,7 @@ msgstr "Número de lÃnea:" #: editor/code_editor.cpp msgid "No Matches" -msgstr "Sin soincidencias" +msgstr "Sin coincidencias" #: editor/code_editor.cpp msgid "Replaced %d occurrence(s)." @@ -467,11 +467,11 @@ msgstr "Quitar" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" -msgstr "Añadir argumento de llamada Extra:" +msgstr "Añadir argumento extra de llamada:" #: editor/connections_dialog.cpp msgid "Extra Call Arguments:" -msgstr "Argumentos de llamada extras:" +msgstr "Argumentos extras de llamada:" #: editor/connections_dialog.cpp msgid "Path to Node:" @@ -479,7 +479,7 @@ msgstr "Ruta al nodo:" #: editor/connections_dialog.cpp msgid "Make Function" -msgstr "Crear runción" +msgstr "Crear función" #: editor/connections_dialog.cpp msgid "Deferred" @@ -516,9 +516,8 @@ msgid "Connecting Signal:" msgstr "Conectando señal:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Disconnect '%s' from '%s'" -msgstr "Conectar «%s» a «%s»" +msgstr "Desconectar '%s' de '%s'" #: editor/connections_dialog.cpp msgid "Connect.." @@ -534,9 +533,8 @@ msgid "Signals" msgstr "Señales" #: editor/create_dialog.cpp -#, fuzzy msgid "Change %s Type" -msgstr "Cambiar tipo" +msgstr "Cambiar el tipo de %s" #: editor/create_dialog.cpp editor/project_settings_editor.cpp #: modules/visual_script/visual_script_editor.cpp @@ -544,9 +542,8 @@ msgid "Change" msgstr "Cambiar" #: editor/create_dialog.cpp -#, fuzzy msgid "Create New %s" -msgstr "Crear nuevo" +msgstr "Crear nuevo %s" #: editor/create_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp @@ -629,7 +626,7 @@ msgstr "Editor de dependencias" #: editor/dependency_editor.cpp msgid "Search Replacement Resource:" -msgstr "Buscar reemplazo de recurso:" +msgstr "Buscar recurso de reemplazo:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help.cpp editor/editor_node.cpp editor/filesystem_dock.cpp @@ -659,9 +656,8 @@ msgstr "" "¿Seguro que quieres quitarlos? (No puedes deshacerlo)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Cannot remove:" -msgstr "No se puede eliminar:\n" +msgstr "No se puede eliminar:" #: editor/dependency_editor.cpp msgid "Error loading:" @@ -737,16 +733,15 @@ msgstr "Contribuidores de Godot" #: editor/editor_about.cpp msgid "Project Founders" -msgstr "Los Fundadores del Proyecto" +msgstr "Fundadores del proyecto" #: editor/editor_about.cpp msgid "Lead Developer" msgstr "Desarrollador Principal" #: editor/editor_about.cpp -#, fuzzy msgid "Project Manager " -msgstr "Administrador de proyectos" +msgstr "Administrador de proyectos " #: editor/editor_about.cpp msgid "Developers" @@ -770,15 +765,15 @@ msgstr "Mini Patrocinadores" #: editor/editor_about.cpp msgid "Gold Donors" -msgstr "Donadores Oro" +msgstr "Donantes Oro" #: editor/editor_about.cpp msgid "Silver Donors" -msgstr "Donadores Plata" +msgstr "Donantes Plata" #: editor/editor_about.cpp msgid "Bronze Donors" -msgstr "Donadores Bronce" +msgstr "Donantes de Bronce" #: editor/editor_about.cpp msgid "Donors" @@ -818,7 +813,7 @@ msgstr "Licencias" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Error opening package file, not in zip format." -msgstr "Error al abrir el paquete, no se encuentra en formato zip." +msgstr "Error al abrir el archivo empaquetado, no tiene formato zip." #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" @@ -831,7 +826,7 @@ msgstr "¡El paquete se ha instalado correctamente!" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Success!" -msgstr "Finalizado!" +msgstr "¡Finalizado!" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -852,12 +847,11 @@ msgstr "Añadir Efecto" #: editor/editor_audio_buses.cpp msgid "Rename Audio Bus" -msgstr "Renombrar Audio Bus" +msgstr "Renombrar bus de audio" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Change Audio Bus Volume" -msgstr "Alternar Audio Bus Solo" +msgstr "Cambiar volumen del bus de audio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Solo" @@ -869,11 +863,11 @@ msgstr "Alternar Mute del Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Bypass Effects" -msgstr "Alternar efectos de bypass del Bus de Audio" +msgstr "Alternar puenteado de efectos en Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Select Audio Bus Send" -msgstr "Seleccionar Bus de Audio de envÃo" +msgstr "Seleccionar envÃo a bus de audio" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus Effect" @@ -901,7 +895,7 @@ msgstr "Silenciar" #: editor/editor_audio_buses.cpp msgid "Bypass" -msgstr "Sobrepasar" +msgstr "Puentear" #: editor/editor_audio_buses.cpp msgid "Bus options" @@ -922,7 +916,7 @@ msgstr "Borrar Efecto" #: editor/editor_audio_buses.cpp msgid "Audio" -msgstr "" +msgstr "Audio" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus" @@ -930,7 +924,7 @@ msgstr "Añadir Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Master bus can't be deleted!" -msgstr "¡El Bus Maestro no puede ser borrado!" +msgstr "¡No se puede borrar el Bus Maestro!" #: editor/editor_audio_buses.cpp msgid "Delete Audio Bus" @@ -942,7 +936,7 @@ msgstr "Duplicar Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Reset Bus Volume" -msgstr "Restablecer Volumen de Bus" +msgstr "Restablecer Volumen del Bus" #: editor/editor_audio_buses.cpp msgid "Move Audio Bus" @@ -950,15 +944,15 @@ msgstr "Mover Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Save Audio Bus Layout As.." -msgstr "Guardar formato de los Audio Bus como..." +msgstr "Guardar configuración de los Buses de Audio como..." #: editor/editor_audio_buses.cpp msgid "Location for New Layout.." -msgstr "Ruta al nuevo diseño.." +msgstr "Ruta para nueva configuración.." #: editor/editor_audio_buses.cpp msgid "Open Audio Bus Layout" -msgstr "Abrir diseño del Audio Bus" +msgstr "Abrir configuración de Bus de Audio" #: editor/editor_audio_buses.cpp msgid "There is no 'res://default_bus_layout.tres' file." @@ -966,7 +960,7 @@ msgstr "No existe el archivo 'res://default_bus_layout.tres'." #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." -msgstr "Archivo inválido, no es un formato de bus de audio" +msgstr "Archivo inválido, no es una configuración de bus de audio." #: editor/editor_audio_buses.cpp msgid "Add Bus" @@ -974,7 +968,7 @@ msgstr "Añadir Bus" #: editor/editor_audio_buses.cpp msgid "Create a new Bus Layout." -msgstr "Crear nuevo Formato de Bus de Audio." +msgstr "Crear nueva configuración de Bus de Audio." #: editor/editor_audio_buses.cpp editor/property_editor.cpp #: editor/script_create_dialog.cpp @@ -983,7 +977,7 @@ msgstr "Cargar" #: editor/editor_audio_buses.cpp msgid "Load an existing Bus Layout." -msgstr "Cargar un Fomato de Bus de Audio existente." +msgstr "Cargar una configuración de Bus de Audio existente." #: editor/editor_audio_buses.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -992,15 +986,15 @@ msgstr "Guardar como" #: editor/editor_audio_buses.cpp msgid "Save this Bus Layout to a file." -msgstr "Guardar este Formato Bus como..." +msgstr "Guardar la configuración de este Bus a un archivo." #: editor/editor_audio_buses.cpp editor/import_dock.cpp msgid "Load Default" -msgstr "Cargar Predeterminado" +msgstr "Cargar Ajuste Predeterminado" #: editor/editor_audio_buses.cpp msgid "Load the default Bus Layout." -msgstr "Cargar Formato de Bus predeterminado." +msgstr "Cargar configuración de Bus por defecto." #: editor/editor_autoload_settings.cpp msgid "Invalid name." @@ -1013,20 +1007,20 @@ msgstr "Letras válidas:" #: editor/editor_autoload_settings.cpp msgid "Invalid name. Must not collide with an existing engine class name." msgstr "" -"El nombre no es correcto. No puede coincidir con un nombre de clase que ya " -"existe en el motor gráfico." +"El nombre no es correcto. No puede coincidir con el nombre de una clase que " +"ya exista en el motor gráfico." #: editor/editor_autoload_settings.cpp msgid "Invalid name. Must not collide with an existing buit-in type name." msgstr "" -"El nombre no es correcto. No puede coincidir con un nombre de tipo " -"predeterminado que ya existe en el motor gráfico." +"El nombre no es correcto. No puede coincidir con un nombre de tipo que ya " +"esté integrado en el motor gráfico." #: editor/editor_autoload_settings.cpp msgid "Invalid name. Must not collide with an existing global constant name." msgstr "" "El nombre no es correcto. No puede coincidir con un nombre de constante " -"global que ya existe en el motor gráfico." +"global ya existente en el motor gráfico." #: editor/editor_autoload_settings.cpp msgid "Invalid Path." @@ -1034,7 +1028,7 @@ msgstr "Ruta incorrecta." #: editor/editor_autoload_settings.cpp msgid "File does not exist." -msgstr "El archivo existe." +msgstr "El archivo no existe." #: editor/editor_autoload_settings.cpp msgid "Not in resource path." @@ -1103,17 +1097,16 @@ msgid "Updating scene.." msgstr "Actualizando escena.." #: editor/editor_data.cpp -#, fuzzy msgid "[empty]" -msgstr "(vacÃo)" +msgstr "[vacÃo]" #: editor/editor_data.cpp msgid "[unsaved]" -msgstr "" +msgstr "[no guardado]" #: editor/editor_dir_dialog.cpp msgid "Please select a base directory first" -msgstr "Por favor seleccione primero un directorio base" +msgstr "Por favor, primero seleccione un directorio base" #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1142,16 +1135,15 @@ msgstr "Elegir" #: editor/editor_export.cpp msgid "Storing File:" -msgstr "Almacén de archivo:" +msgstr "Archivo de almacenamiento:" #: editor/editor_export.cpp msgid "Packing" msgstr "Empaquetando" #: editor/editor_export.cpp platform/javascript/export/export.cpp -#, fuzzy msgid "Template file not found:" -msgstr "No se encontró archivo plantilla:\n" +msgstr "No se encontró archivo de plantilla:" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File Exists, Overwrite?" @@ -1170,9 +1162,8 @@ msgid "Show In File Manager" msgstr "Mostrar en el navegador de archivos" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "New Folder.." -msgstr "Crear carpeta" +msgstr "Nueva carpeta..." #: editor/editor_file_dialog.cpp msgid "Refresh" @@ -1267,11 +1258,11 @@ msgstr "Archivo:" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Must use a valid extension." -msgstr "Debe ser una extensión válida." +msgstr "Debe tener una extensión válida." #: editor/editor_file_system.cpp msgid "ScanSources" -msgstr "AnalizandoFuentes" +msgstr "Analizando fuentes" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -1363,19 +1354,18 @@ msgid "Description" msgstr "Descripción" #: editor/editor_help.cpp -#, fuzzy msgid "Online Tutorials:" -msgstr "Tutoriales" +msgstr "Tutoriales en lÃnea:" #: editor/editor_help.cpp -#, fuzzy msgid "" "There are currently no tutorials for this class, you can [color=$color][url=" "$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/" "url][/color]." msgstr "" -"Actualmente no hay una descripción para este método. Por favor, ¡ayúdanos " -"[color=$color][url=$url]aportando una[/url][/color]!" +"De momento no hay tutoriales para esta clase, puedes [color=$color][url=" +"$url]añadir uno[/url][/color] o [color=$color][url=$url2]pedir uno[color=" +"$color][url=$url2]." #: editor/editor_help.cpp msgid "Properties" @@ -1383,7 +1373,7 @@ msgstr "Propiedades" #: editor/editor_help.cpp msgid "Property Description:" -msgstr "Descripción de Propiedad:" +msgstr "Descripción de la Propiedad:" #: editor/editor_help.cpp msgid "" @@ -1429,9 +1419,8 @@ msgid "Clear" msgstr "Borrar todo" #: editor/editor_log.cpp -#, fuzzy msgid "Clear Output" -msgstr "Salida" +msgstr "Borrar salida" #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Error saving resource!" @@ -1468,7 +1457,7 @@ msgstr "Error al analizar '%s'." #: editor/editor_node.cpp msgid "Unexpected end of file '%s'." -msgstr "Fin de archivo inesperado '%s'." +msgstr "Fin de archivo '%s' inesperado." #: editor/editor_node.cpp msgid "Missing '%s' or its dependencies." @@ -1495,13 +1484,12 @@ msgid "This operation can't be done without a tree root." msgstr "Esta operación no puede realizarse sin una escena raÃz." #: editor/editor_node.cpp -#, fuzzy msgid "" "Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " "be satisfied." msgstr "" -"No se pudo guardar la escena. Es posible que no se hayan podido satisfacer " -"las dependencias (instancias)." +"No se pudo guardar la escena. Las dependencias (instancias o herencia) no se " +"pudieron resolver." #: editor/editor_node.cpp msgid "Failed to load resource." @@ -1574,7 +1562,7 @@ msgid "" "understand this workflow." msgstr "" "Esta escena ha sido importada, por lo tanto, los cambios no se mantendrán.\n" -"Instanciarlo o heredarlo permitirá hacerle cambios.\n" +"Instanciarla o heredarla permitirá hacerle cambios.\n" "Por favor, lee la documentación referente a la importación de escenas para " "entender mejor el flujo de trabajo." @@ -1589,12 +1577,10 @@ msgstr "" "mejor el flujo de trabajo." #: editor/editor_node.cpp -#, fuzzy msgid "Expand all properties" msgstr "Expandir todas las propiedades" #: editor/editor_node.cpp -#, fuzzy msgid "Collapse all properties" msgstr "Colapsar todo" @@ -1616,11 +1602,11 @@ msgstr "Copiar recurso" #: editor/editor_node.cpp msgid "Make Built-In" -msgstr "Hacerlo integrado" +msgstr "Convertirlo en integrado" #: editor/editor_node.cpp msgid "Make Sub-Resources Unique" -msgstr "Crear subrecurso único" +msgstr "Hacer sub-recursos únicos" #: editor/editor_node.cpp msgid "Open in Help" @@ -1647,8 +1633,8 @@ msgid "" "category." msgstr "" "La escena '%s' seleccionada no existe, ¿seleccionar una válida?\n" -"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categoria " -"'aplicacion'." +"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categorÃa " +"'aplicación'." #: editor/editor_node.cpp msgid "" @@ -1658,13 +1644,13 @@ msgid "" msgstr "" "La escena '%s' seleccionada no es un archivo de escena, ¿seleccionar uno " "válido?\n" -"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categoria " -"'aplicacion'." +"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categorÃa " +"'aplicación'." #: editor/editor_node.cpp msgid "Current scene was never saved, please save it prior to running." msgstr "" -"La escena actual nunca se guardó. Favor de guardarla antes de ejecutar." +"La escena actual nunca se guardó. Por favor, guárdela antes de ejecutar." #: editor/editor_node.cpp msgid "Could not start subprocess!" @@ -1717,7 +1703,7 @@ msgstr "Esta operación no puede realizarse sin una escena." #: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "Exportar biblioteca de modelos" +msgstr "Exportar biblioteca de mallas" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." @@ -1745,7 +1731,9 @@ msgstr "Revertir" #: editor/editor_node.cpp msgid "This action cannot be undone. Revert anyway?" -msgstr "Esta acción es irreversible. ¿Quieres revertirla de todos modos?" +msgstr "" +"Esta acción no se podrá volver a realizar. ¿Quieres revertirla de todos " +"modos?" #: editor/editor_node.cpp msgid "Quick Run Scene.." @@ -1822,7 +1810,7 @@ msgid "" "Scene '%s' was automatically imported, so it can't be modified.\n" "To make changes to it, a new inherited scene can be created." msgstr "" -"La escena '%s' fue importado automáticamente, por lo tanto no puede ser " +"La escena '%s' fue importada automáticamente, por lo tanto no puede ser " "modificada.\n" "Para poder modificarla, se tiene que crear una nueva escena heredada." @@ -1886,9 +1874,8 @@ msgid "Distraction Free Mode" msgstr "Modo sin distracciones" #: editor/editor_node.cpp -#, fuzzy msgid "Toggle distraction-free mode." -msgstr "Alternar Modo sin distracciones." +msgstr "Alternar modo sin distracciones." #: editor/editor_node.cpp msgid "Add a new scene." @@ -1952,11 +1939,11 @@ msgstr "Convertir a.." #: editor/editor_node.cpp msgid "MeshLibrary.." -msgstr "MeshLibrary.." +msgstr "LibrerÃa de mallas.." #: editor/editor_node.cpp msgid "TileSet.." -msgstr "TileSet.." +msgstr "\"TileSet\".." #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp @@ -1974,7 +1961,7 @@ msgstr "Revertir escena" #: editor/editor_node.cpp msgid "Miscellaneous project or scene-wide tools." -msgstr "Herramientas varias o de escenas." +msgstr "Herramientas variadas de proyecto o escena." #: editor/editor_node.cpp msgid "Project" @@ -1998,7 +1985,7 @@ msgstr "Herramientas" #: editor/editor_node.cpp msgid "Quit to Project List" -msgstr "Salir al listado del proyecto" +msgstr "Salir al listado de proyectos" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Debug" @@ -2013,8 +2000,8 @@ msgid "" "When exporting or deploying, the resulting executable will attempt to " "connect to the IP of this computer in order to be debugged." msgstr "" -"Al exportar o publicarlo, el ejecutable tratará de conectarse a la IP de " -"este equipo para iniciar la depuración." +"Al exportar o publicar, el ejecutable tratará de conectarse a la IP de este " +"equipo para iniciar la depuración." #: editor/editor_node.cpp msgid "Small Deploy with Network FS" @@ -2029,7 +2016,7 @@ msgid "" "On Android, deploy will use the USB cable for faster performance. This " "option speeds up testing for games with a large footprint." msgstr "" -"Cuando esta opción está activa, al exportar o publicar se producirá un " +"Cuando esta opción está activa, al exportar o publicar se creará un " "ejecutable mÃnimo.\n" "El sistema de archivos del proyecto se pasará desde el editor por la red.\n" "En Android, publicar utilizará el cable USB para un mejor rendimiento. Esta " @@ -2044,8 +2031,8 @@ msgid "" "Collision shapes and raycast nodes (for 2D and 3D) will be visible on the " "running game if this option is turned on." msgstr "" -"Los Collision shapes y nodos raycast (para 2D y 3D) seran visibiles durante " -"la ejecución del juego cuando esta opción queda activada." +"Los \"Collision Shapes\" y los nodos \"raycast\" (para 2D y 3D) serán " +"visibles durante la ejecución del juego cuando esta opción esté activada." #: editor/editor_node.cpp msgid "Visible Navigation" @@ -2056,7 +2043,7 @@ msgid "" "Navigation meshes and polygons will be visible on the running game if this " "option is turned on." msgstr "" -"Si activas esta opción podrás ver los modelos y polÃgonos de navegación " +"Si activas esta opción podrás ver las mallas y polÃgonos de navegación " "durante la ejecución del juego." #: editor/editor_node.cpp @@ -2070,7 +2057,7 @@ msgid "" "When used remotely on a device, this is more efficient with network " "filesystem." msgstr "" -"Cuando esta opción este encendida, cualquier cambio hecho a la escena en el " +"Cuando esta opción este activada, cualquier cambio hecho a la escena en el " "editor sera replicado en el juego en ejecución.\n" "Cuando se usa remotamente en un dispositivo, esto es mas eficiente con un " "sistema de archivos remoto." @@ -2086,7 +2073,7 @@ msgid "" "When used remotely on a device, this is more efficient with network " "filesystem." msgstr "" -"Cuando esta opción esta activa, cualquier script que se guarde sera vuelto a " +"Cuando esta opción esté activa, cualquier script que se guarde se volverá a " "cargar en el juego en ejecución.\n" "Cuando se use remotamente en un dispositivo, esto es mas eficiente con un " "sistema de archivos de red." @@ -2109,7 +2096,7 @@ msgstr "Modo Pantalla Completa" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" -msgstr "Cargando Plantillas de Exportación" +msgstr "Cargar Plantillas de Exportación" #: editor/editor_node.cpp msgid "Help" @@ -2136,7 +2123,7 @@ msgstr "P&R" #: editor/editor_node.cpp msgid "Issue Tracker" -msgstr "Registros de problemas" +msgstr "Registro de problemas" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -2188,7 +2175,7 @@ msgstr "Reproducir escena personalizada" #: editor/editor_node.cpp msgid "Spins when the editor window repaints!" -msgstr "Gira cuando la ventana del editor repinta!" +msgstr "¡Gira cuando la ventana del editor redibuja!" #: editor/editor_node.cpp msgid "Update Always" @@ -2240,7 +2227,7 @@ msgstr "Propiedades del objeto." #: editor/editor_node.cpp msgid "Changes may be lost!" -msgstr "¡Se pueden perder los cambios!" +msgstr "¡Se perderán los cambios realizados!" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp #: editor/project_manager.cpp @@ -2325,7 +2312,7 @@ msgstr "Abrir Editor anterior" #: editor/editor_plugin.cpp msgid "Creating Mesh Previews" -msgstr "Creando vistas previas de los modelos 3D" +msgstr "Creando vistas previas de las mallas" #: editor/editor_plugin.cpp msgid "Thumbnail.." @@ -2366,7 +2353,7 @@ msgstr "Medida:" #: editor/editor_profiler.cpp msgid "Frame Time (sec)" -msgstr "Duracion de cuadro (seg)" +msgstr "Duración de cuadro (seg)" #: editor/editor_profiler.cpp msgid "Average Time (sec)" @@ -2377,9 +2364,8 @@ msgid "Frame %" msgstr "% de cuadro" #: editor/editor_profiler.cpp -#, fuzzy msgid "Physics Frame %" -msgstr "% de cuadro fijo" +msgstr "% de cuadro fÃsico" #: editor/editor_profiler.cpp editor/script_editor_debugger.cpp msgid "Time:" @@ -2398,14 +2384,12 @@ msgid "Frame #:" msgstr "Nº de cuadro:" #: editor/editor_profiler.cpp -#, fuzzy msgid "Time" -msgstr "Tiempo:" +msgstr "Tiempo" #: editor/editor_profiler.cpp -#, fuzzy msgid "Calls" -msgstr "Llamada" +msgstr "Llamadas" #: editor/editor_run_native.cpp msgid "Select device from the list" @@ -2416,7 +2400,7 @@ msgid "" "No runnable export preset found for this platform.\n" "Please add a runnable preset in the export menu." msgstr "" -"No se ha encontrado ningún preset ejecutable de exportación para esta " +"No se ha encontrado ningún preset de exportación ejecutable para esta " "plataforma.\n" "Por favor, añade un preset ejecutable en el menú de exportación." @@ -2490,7 +2474,7 @@ msgstr "Obteniendo mirrors, por favor espere..." #: editor/export_template_manager.cpp msgid "Remove template version '%s'?" -msgstr "Eliminar diseño de versión '%s'?" +msgstr "¿Eliminar plantilla versión '%s'?" #: editor/export_template_manager.cpp msgid "Can't open export templates zip." @@ -2498,24 +2482,15 @@ msgstr "No se puede abir el zip de plantillas de exportación." #: editor/export_template_manager.cpp msgid "Invalid version.txt format inside templates." -msgstr "version.txt invalido en el diseño." - -#: editor/export_template_manager.cpp -#, fuzzy -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Formato de version.txt inválido. Revision no es un identificador válido." +msgstr "Formato de \"version.txt\" inválido dentro de las plantillas." #: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "No se ha encontrado el archivo version.txt dentro de las plantillas." #: editor/export_template_manager.cpp -#, fuzzy msgid "Error creating path for templates:" -msgstr "Error al crear ruta para las plantillas:\n" +msgstr "Error al crear ruta para las plantillas:" #: editor/export_template_manager.cpp msgid "Extracting Export Templates" @@ -2550,9 +2525,8 @@ msgstr "No responde." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Request Failed." -msgstr "Solicitud fallida." +msgstr "Petición fallida." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -2565,10 +2539,6 @@ msgid "Failed:" msgstr "Fallido:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "No se puede escribir el archivo." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Descarga completada." @@ -2577,9 +2547,8 @@ msgid "Error requesting url: " msgstr "Error al solicitar url: " #: editor/export_template_manager.cpp -#, fuzzy msgid "Connecting to Mirror.." -msgstr "Conectando.." +msgstr "Intentando conexión alternativa.." #: editor/export_template_manager.cpp msgid "Disconnected" @@ -2599,7 +2568,6 @@ msgid "Connecting.." msgstr "Conectando.." #: editor/export_template_manager.cpp -#, fuzzy msgid "Can't Connect" msgstr "No se puede conectar" @@ -2642,10 +2610,9 @@ msgstr "Eliminar plantilla" #: editor/export_template_manager.cpp msgid "Select template file" -msgstr "Seleccionar archivo de plantilla" +msgstr "Seleccionar archivo plantilla" #: editor/export_template_manager.cpp -#, fuzzy msgid "Export Template Manager" msgstr "Gestor de plantillas de exportación" @@ -2678,45 +2645,38 @@ msgid "View items as a list" msgstr "Ver elementos como una lista" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Status: Import of file failed. Please fix file and reimport manually." msgstr "" -"\n" -"Estado: No se pudo importar el archivo. Por favor, arregla el archivo e " -"impórtalo manualmente." +"Estado: No se pudo importar el archivo. Por favor, arregla el archivo y " +"reimpórtalo manualmente." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Cannot move/rename resources root." -msgstr "No se puede mover/renombrar la raÃz de recursos." +msgstr "No se puede mover/renombrar la raÃz de los recursos." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Cannot move a folder into itself." -msgstr "No se puede importar una carpeta sobre si misma.\n" +msgstr "No se puede mover una carpeta a dentro de sà misma." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Error moving:" -msgstr "Error al mover:\n" +msgstr "Error al mover:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Error duplicating:" -msgstr "Error al cargar:" +msgstr "Error al duplicar:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Unable to update dependencies:" -msgstr "No se ha podido actualizar las dependencias:\n" +msgstr "No se han podido actualizar las dependencias:" #: editor/filesystem_dock.cpp msgid "No name provided" -msgstr "No se proveyó un nombre" +msgstr "No se proporcionó un nombre" #: editor/filesystem_dock.cpp msgid "Provided name contains invalid characters" -msgstr "El nombre obtenido contiene caracteres inválidos" +msgstr "El nombre proporcionado contiene caracteres inválidos" #: editor/filesystem_dock.cpp msgid "No name provided." @@ -2739,14 +2699,12 @@ msgid "Renaming folder:" msgstr "Renombrar carpeta:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Duplicating file:" -msgstr "Duplicar" +msgstr "Duplicando archivo:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Duplicating folder:" -msgstr "Renombrar carpeta:" +msgstr "Duplicando carpeta:" #: editor/filesystem_dock.cpp msgid "Expand all" @@ -2765,9 +2723,8 @@ msgid "Move To.." msgstr "Mover a.." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scene(s)" -msgstr "Abrir escena" +msgstr "Abrir escena/s" #: editor/filesystem_dock.cpp msgid "Instance" @@ -2778,14 +2735,12 @@ msgid "Edit Dependencies.." msgstr "Editar dependencias.." #: editor/filesystem_dock.cpp -#, fuzzy msgid "View Owners.." msgstr "Ver propietarios.." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Duplicate.." -msgstr "Duplicar" +msgstr "Duplicar.." #: editor/filesystem_dock.cpp msgid "Previous Directory" @@ -2834,14 +2789,12 @@ msgid "Remove from Group" msgstr "Quitar del grupo" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Import as Single Scene" -msgstr "Importando escena…" +msgstr "Importar como escena individual" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Import with Separate Animations" -msgstr "Importar con materiales separados" +msgstr "Importar con animaciones separadas" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials" @@ -2852,29 +2805,24 @@ msgid "Import with Separate Objects" msgstr "Importar con objetos separados" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Import with Separate Objects+Materials" msgstr "Importar con objetos y materiales separados" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Import with Separate Objects+Animations" -msgstr "Importar con objetos y materiales separados" +msgstr "Importar con objetos y animaciones separados" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Import with Separate Materials+Animations" -msgstr "Importar con materiales separados" +msgstr "Importar con materiales y animaciones separados" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Import with Separate Objects+Materials+Animations" -msgstr "Importar con objetos y materiales separados" +msgstr "Importar con objetos, materiales y animaciones separados" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Import as Multiple Scenes" -msgstr "Importar escena 3D" +msgstr "Importar como múltiples escenas" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes+Materials" @@ -2890,14 +2838,12 @@ msgid "Importing Scene.." msgstr "Importando escena.." #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Generating Lightmaps" -msgstr "Transfiriendo a «lightmaps»:" +msgstr "Generando \"Lightmaps\"" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Generating for Mesh: " -msgstr "Generar AABB" +msgstr "Generando para modelo: " #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script.." @@ -2929,21 +2875,18 @@ msgid "Clear Default for '%s'" msgstr "Borrar por defecto para '%s'" #: editor/import_dock.cpp -#, fuzzy msgid " Files" -msgstr "Archivo" +msgstr " Archivos" #: editor/import_dock.cpp -#, fuzzy msgid "Import As:" -msgstr "Importar" +msgstr "Importar como:" #: editor/import_dock.cpp editor/property_editor.cpp msgid "Preset.." msgstr "Ajuste.." #: editor/import_dock.cpp -#, fuzzy msgid "Reimport" msgstr "Reimportar" @@ -2971,9 +2914,8 @@ msgid "Edit Poly" msgstr "Editar polÃgono" #: editor/plugins/abstract_polygon_2d_editor.cpp -#, fuzzy msgid "Insert Point" -msgstr "Insertando" +msgstr "Insertar punto" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/collision_polygon_editor_plugin.cpp @@ -2986,9 +2928,8 @@ msgid "Remove Poly And Point" msgstr "Quitar polÃgono y punto" #: editor/plugins/abstract_polygon_2d_editor.cpp -#, fuzzy msgid "Create a new polygon from scratch" -msgstr "Crea un nuevo polÃgono desde cero." +msgstr "Crear un nuevo polÃgono desde cero" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "" @@ -3003,9 +2944,8 @@ msgstr "" "Click derecho: Borrar punto." #: editor/plugins/abstract_polygon_2d_editor.cpp -#, fuzzy msgid "Delete points" -msgstr "Eliminar punto" +msgstr "Eliminar puntos" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" @@ -3024,9 +2964,8 @@ msgid "Change Animation Name:" msgstr "Cambiar nombre de animación:" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Delete Animation?" -msgstr "Duplicar animación" +msgstr "¿Eliminar animación?" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp @@ -3107,7 +3046,7 @@ msgstr "Reproducir animación seleccionada desde el principio. (Mayús + D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" -msgstr "Reproducir animación seleccionada desde la posicion actual. (D)" +msgstr "Reproducir animación seleccionada desde la posición actual. (D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." @@ -3115,7 +3054,7 @@ msgstr "Posición de animación (en segundos)." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Scale animation playback globally for the node." -msgstr "Escalar la reproducción de la animación globalmente para el nodo." +msgstr "Escalar globalmente la reproducción de la animación para el nodo." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create new animation in player." @@ -3135,7 +3074,7 @@ msgstr "Guardar la animación actual" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." -msgstr "Lista de animaciones en el reproductor." +msgstr "Mostrar la lista de animaciones en el reproductor." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Autoplay on Load" @@ -3143,7 +3082,7 @@ msgstr "Autoreproducir al cargar" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Target Blend Times" -msgstr "Editar Blend Times Objetivo" +msgstr "Editar tiempos de mezcla de selección" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Tools" @@ -3162,36 +3101,30 @@ msgid "Enable Onion Skinning" msgstr "Activar Papel Cebolla" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Directions" -msgstr "Selecciones:" +msgstr "Direcciones" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Past" -msgstr "Pegar" +msgstr "Anterior" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Future" -msgstr "Textura" +msgstr "Posterior" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Depth" msgstr "Profundidad" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "1 step" msgstr "1 paso" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "2 steps" msgstr "2 pasos" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "3 steps" msgstr "3 pasos" @@ -3201,7 +3134,7 @@ msgstr "Solo las Diferencias" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Force White Modulate" -msgstr "" +msgstr "Forzar modulación hacia el blanco" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Include Gizmos (3D)" @@ -3244,9 +3177,8 @@ msgid "New name:" msgstr "Nuevo nombre:" #: editor/plugins/animation_tree_editor_plugin.cpp -#, fuzzy msgid "Edit Filters" -msgstr "Editar filtros de nodo" +msgstr "Editar filtros" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp @@ -3255,15 +3187,15 @@ msgstr "Escala:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Fade In (s):" -msgstr "Aparición (s):" +msgstr "Fundido de entrada (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Fade Out (s):" -msgstr "Desaparición (s):" +msgstr "Fundido de salida (s):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend" -msgstr "Mezclar" +msgstr "Mezcla" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Mix" @@ -3292,15 +3224,15 @@ msgstr "Cantidad:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend:" -msgstr "Blend:" +msgstr "Mezcla:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend 0:" -msgstr "Blend 0:" +msgstr "Mezcla 0:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend 1:" -msgstr "Blend 1:" +msgstr "Mezcla 1:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "X-Fade Time (s):" @@ -3360,7 +3292,7 @@ msgstr "Nodo Blend4" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeScale Node" -msgstr "Nodo TimeScale" +msgstr "Nodo TimeScale (Escala de tiempo)" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeSeek Node" @@ -3383,9 +3315,8 @@ msgid "Filters.." msgstr "Filtros.." #: editor/plugins/animation_tree_editor_plugin.cpp -#, fuzzy msgid "AnimationTree" -msgstr "Animación" +msgstr "Ãrbol de animación" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Free" @@ -3405,10 +3336,9 @@ msgstr "No se ha podido resolver el nombre de Dominio:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connection error, please try again." -msgstr "Error de conexion, por favor intente otra vez." +msgstr "Error de conexión, por favor inténtelo otra vez." #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Can't connect to host:" msgstr "No se puede conectar al host:" @@ -3417,18 +3347,16 @@ msgid "No response from host:" msgstr "No hay respuesta desde el host:" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Request failed, return code:" -msgstr "Petición falida, código de retorno:" +msgstr "Petición fallida, código:" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Request failed, too many redirects" msgstr "Petición fallida, demasiadas redirecciones" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Bad download hash, assuming file has been tampered with." -msgstr "Error de descarga, al pareser el archivo ha sido manipulado." +msgstr "Error de descarga, al parecer el archivo ha sido manipulado." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Expected:" @@ -3464,7 +3392,7 @@ msgstr "Inactivo" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Retry" -msgstr "Reintente" +msgstr "Reintentar" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download Error" @@ -3472,7 +3400,7 @@ msgstr "Error de Descarga" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download for this asset is already in progress!" -msgstr "Este asset ya esta descargandose!" +msgstr "¡Éste asset ya está descargándose!" #: editor/plugins/asset_library_editor_plugin.cpp msgid "first" @@ -3488,7 +3416,7 @@ msgstr "siguiente" #: editor/plugins/asset_library_editor_plugin.cpp msgid "last" -msgstr "ultimo" +msgstr "último" #: editor/plugins/asset_library_editor_plugin.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -3539,21 +3467,27 @@ msgid "" "Save your scene (for images to be saved in the same dir), or pick a save " "path from the BakedLightmap properties." msgstr "" +"No se puede encontrar una ruta válida para las imágenes \"lightmap\".\n" +"Guarda la escena (para que las imágenes se guarden en el mismo directorio), " +"o selecciona otra ruta desde las propiedades del \"BackedLightmap\"." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake " "Light' flag is on." msgstr "" +"No hay mallas que pre-calcular. Asegúrese de que contienen el canal UV2 y el " +"flag 'Bake Light' esté activo." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Failed creating lightmap images, make sure path is writable." msgstr "" +"Error al crear las imágenes del \"lighmap\", asegúrate de que se puede " +"escribir en la ruta." #: editor/plugins/baked_lightmap_editor_plugin.cpp -#, fuzzy msgid "Bake Lightmaps" -msgstr "Transfiriendo a «lightmaps»:" +msgstr "Calculando «lightmaps»" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -3562,7 +3496,7 @@ msgstr "Vista previa" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap" -msgstr "Ajustes de fijado" +msgstr "Configurar ajuste" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -3595,29 +3529,24 @@ msgid "Move vertical guide" msgstr "Mover GuÃa Vertical" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create new vertical guide" -msgstr "Crear script" +msgstr "Crear nueva guÃa vertical" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Remove vertical guide" -msgstr "Quitar variable" +msgstr "Quitar guÃa vertical" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Move horizontal guide" -msgstr "Mover Punto en Curva" +msgstr "Mover guÃa horizontal" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create new horizontal guide" -msgstr "Crear script" +msgstr "Crear nueva guÃa horizontal" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Remove horizontal guide" -msgstr "Quitar claves incorrectas" +msgstr "Quitar guÃa horizontal" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Create new horizontal and vertical guides" @@ -3632,14 +3561,12 @@ msgid "Edit CanvasItem" msgstr "Editar CanvasItem" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Anchors only" -msgstr "Ancla" +msgstr "Sólo anclado" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Anchors and Margins" -msgstr "Cambiar anclas" +msgstr "Cambiar anclas y márgenes" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Change Anchors" @@ -3659,17 +3586,17 @@ msgstr "Arrastrar: Rotar" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+Drag: Move" -msgstr "Alt+Arrastrae: Mover" +msgstr "Alt+Arrastrar: Mover" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." msgstr "" -"Presioná 'v' para Cambiar el Pivote, 'Shift+v' para Arrastrar el Pivote (al " +"Presiona 'v' para Cambiar el Pivote, 'Shift+v' para Arrastrar el Pivote (al " "mover)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+RMB: Depth list selection" -msgstr "Alt+Click Der.: Selección en depth list" +msgstr "Alt+Click Der.: Selección en listado de solapamientos" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move Mode" @@ -3685,7 +3612,7 @@ msgid "" "Show a list of all objects at the position clicked\n" "(same as Alt+RMB in select mode)." msgstr "" -"Mostrar una lista de todos los objetos en la posicion cliqueada\n" +"Mostrar una lista de todos los objetos en la posición cliqueada\n" "(igual que Alt+Click Der. en modo selección)." #: editor/plugins/canvas_item_editor_plugin.cpp @@ -3697,32 +3624,28 @@ msgid "Pan Mode" msgstr "Modo desplazamiento lateral" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Toggles snapping" -msgstr "Des/activar «breakpoint»" +msgstr "Activar/desactivar fijado" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Snap" -msgstr "Fijar a cuadrÃcula" +msgstr "Usar fijado" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snapping options" -msgstr "Opciones de Animación" +msgstr "Opciones de fijado" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to grid" -msgstr "Modo de fijado:" +msgstr "Ajustar a cuadrÃcula" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Rotation Snap" -msgstr "Fijar rotación" +msgstr "Ajustar rotación" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Configure Snap..." -msgstr "Configurar fijado.." +msgstr "Configurar CuadrÃcula..." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap Relative" @@ -3730,37 +3653,31 @@ msgstr "Fijado relativo" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Pixel Snap" -msgstr "Adherir a pÃxeles" +msgstr "Ajustar a pÃxeles" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart snapping" -msgstr "Ajuste Inteligente" +msgstr "Fijado inteligente" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to parent" -msgstr "Expandir al padre" +msgstr "Ajustar al padre" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to node anchor" -msgstr "Ajustar al Nodo Ancla" +msgstr "Ajustar al anclado del nodo" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to node sides" -msgstr "Ajustar a Lados del Nodo" +msgstr "Ajustar a los lados de los nodos" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to other nodes" -msgstr "Ajustar a Otros Nodos" +msgstr "Ajustar a otros nodos" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to guides" -msgstr "Modo de fijado:" +msgstr "Ajustar a guÃas" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -3770,7 +3687,7 @@ msgstr "Inmovilizar el objeto." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Unlock the selected object (can be moved)." -msgstr "Liberar el objeto." +msgstr "Liberar objeto inmovilizado." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Makes sure the object's children are not selectable." @@ -3789,9 +3706,8 @@ msgid "Clear Bones" msgstr "Reestablecer huesos" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Show Bones" -msgstr "Crear huesos" +msgstr "Mostrar huesos" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -3812,19 +3728,16 @@ msgid "Show Grid" msgstr "Mostrar rejilla" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy -msgid "Show helpers" -msgstr "Crear huesos" +msgid "Show Helpers" +msgstr "Mostrar ayudas" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy -msgid "Show rulers" -msgstr "Crear huesos" +msgid "Show Rulers" +msgstr "Mostrar reglas" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy -msgid "Show guides" -msgstr "Crear huesos" +msgid "Show Guides" +msgstr "Mostrar guÃas" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Selection" @@ -3835,9 +3748,8 @@ msgid "Frame Selection" msgstr "Encuadrar selección" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Layout" -msgstr "Guardar ajustes" +msgstr "Disposición" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Keys" @@ -3864,27 +3776,22 @@ msgid "Drag pivot from mouse position" msgstr "Arrastrar pivote desde la posición del ratón" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Set pivot at mouse position" -msgstr "Establecer pos. de salida de curva" +msgstr "Establecer punto de pivotado en la posición del ratón" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Multiply grid step by 2" -msgstr "Multiplicar paso de cuadÅ•icula por 2" +msgstr "Multiplicar paso de cuadrÃcula por 2" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Divide grid step by 2" msgstr "Dividir paso de cuadrÃcula por 2" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Add %s" -msgstr "Añadir todos" +msgstr "Añadir %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Adding %s..." msgstr "Añadiendo %s..." @@ -3894,7 +3801,7 @@ msgstr "Aceptar" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Cannot instantiate multiple nodes without root." -msgstr "" +msgstr "No se pueden instanciar varios nodos sin un nodo raÃz." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp @@ -3907,18 +3814,16 @@ msgid "Error instancing scene from %s" msgstr "Error al instanciar escena desde %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change default type" -msgstr "Cambiar Valor por Defecto" +msgstr "Cambiar tipo por defecto" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "" "Drag & drop + Shift : Add node as sibling\n" "Drag & drop + Alt : Change node type" msgstr "" -"Arrastrar y soltar + Mayús: Añadir nodo como hermano\n" -"Arrastrar y soltar + Alt: Cambiar tipo de nodo" +"Arrastrar y soltar + Shift : Añadir nodo como hermano\n" +"Arrastrar y soltar + Alt : Cambiar tipo de nodo" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Create Poly3D" @@ -3952,88 +3857,75 @@ msgstr "Actualizar desde escena" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat0" -msgstr "Flat0" +msgstr "Plana0" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat1" -msgstr "Flat1" +msgstr "Plana1" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Ease in" -msgstr "Transición entrada" +msgstr "Transición de entrada" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Ease out" -msgstr "Transición salida" +msgstr "Transición de salida" #: editor/plugins/curve_editor_plugin.cpp msgid "Smoothstep" -msgstr "" +msgstr "Paso suavizado" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Modify Curve Point" -msgstr "Modificar Mapa de Curvas" +msgstr "Modificar punto de la curva" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Modify Curve Tangent" -msgstr "Modificar Mapa de Curvas" +msgstr "Modificar tangente de la curva" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Curve Preset" -msgstr "Cargar recurso" +msgstr "Cargar ajuste predeterminado de curva" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add point" -msgstr "Añadir entrada" +msgstr "Añadir punto" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove point" -msgstr "Quitar Punto de ruta" +msgstr "Quitar punto" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left linear" -msgstr "Lineal" +msgstr "Izquierda lineal" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right linear" -msgstr "Vista derecha" +msgstr "Derecha lineal" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load preset" -msgstr "Cargar recurso" +msgstr "Cargar ajuste predeterminado" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Curve Point" -msgstr "Quitar Punto de ruta" +msgstr "Quitar punto de la curva" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Toggle Curve Linear Tangent" -msgstr "Cambiar tangente de curva lineal" +msgstr "Alternar curva de tangente lineal" #: editor/plugins/curve_editor_plugin.cpp msgid "Hold Shift to edit tangents individually" -msgstr "Mantén Mayus para editar las tangentes individualmente" +msgstr "Mantén Mayús para editar las tangentes individualmente" #: editor/plugins/gi_probe_editor_plugin.cpp msgid "Bake GI Probe" -msgstr "" +msgstr "Precalcular GI Probe" #: editor/plugins/gradient_editor_plugin.cpp -#, fuzzy msgid "Add/Remove Color Ramp Point" -msgstr "Añadir/quitar punto de rampa de color" +msgstr "Añadir/quitar punto en la rampa del degradado" #: editor/plugins/gradient_editor_plugin.cpp #: editor/plugins/shader_graph_editor_plugin.cpp @@ -4086,15 +3978,15 @@ msgstr "Clic derecho: Borrar punto." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh is empty!" -msgstr "¡El modelo está vacÃo!" +msgstr "¡La malla está vacÃa!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" -msgstr "Crear colisión estática triangular" +msgstr "Crear cuerpo estático \"Trimesh\"" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Convex Body" -msgstr "Crear colisión estática convexa" +msgstr "Crear cuerpo estático convexo" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "This doesn't work on scene root!" @@ -4110,31 +4002,33 @@ msgstr "Crear forma convexa" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" -msgstr "Crear modelo de navegación 3D" +msgstr "Crear malla de navegación" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Contained Mesh is not of type ArrayMesh." -msgstr "" +msgstr "La malla que contiene no es del tipo ArrayMesh." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Unwrap failed, mesh may not be manifold?" msgstr "" +"Falló el procedimiento de Unwrapping, ¿Tal vez la malla contenga geometrÃa " +"múltiple o desajustada?" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "No mesh to debug." -msgstr "" +msgstr "No hay malla que depurar." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Model has no UV in this layer" -msgstr "" +msgstr "El modelo no tiene UV en esta capa" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "MeshInstance lacks a Mesh!" -msgstr "¡A MeshInstance le falta un modelo 3D!" +msgstr "¡MeshInstance no tiene malla!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh has not surface to create outlines from!" -msgstr "¡El modelo 3D no tiene una superficie en la que crear contornos!" +msgstr "¡La malla no tiene superficie de la que crear contornos!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Could not create outline!" @@ -4146,15 +4040,15 @@ msgstr "Crear contorno" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh" -msgstr "Modelos 3D" +msgstr "Malla" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Body" -msgstr "Crear colisión estática triangular" +msgstr "Crear cuerpo estático triangular" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Convex Static Body" -msgstr "Crear colisión estática convexa" +msgstr "Crear cuerpo estático convexo" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Collision Sibling" @@ -4166,25 +4060,23 @@ msgstr "Crear colisión hermanada convexa" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh.." -msgstr "Crear modelo 3D de contorno.." +msgstr "Crear contorno de malla.." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "View UV1" -msgstr "Ver" +msgstr "Ver UV1" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "View UV2" -msgstr "Ver" +msgstr "Ver UV2" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Unwrap UV2 for Lightmap/AO" -msgstr "" +msgstr "Desenvuelva UV2 para Lightmap/AO" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh" -msgstr "Crear modelo 3D de contorno" +msgstr "Crear contorno de malla" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Outline Size:" @@ -4193,42 +4085,40 @@ msgstr "Tamaño del contorno:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." msgstr "" -"No se especificó ningún modelo 3D de origen (y no se ha establecido ningún " -"MultiMesh en el nodo)." +"No se especificó malla de origen (y no hay MultiMesh establecido en el nodo)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and MultiMesh contains no Mesh)." msgstr "" -"No se especificó ningún modelo de origen (y MultiMesh no contiene ningún " -"Mesh)." +"No se especificó malla de origen (y MultiMesh no contiene ningún Mesh)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (invalid path)." -msgstr "El origen del modelo es incorrecto (ruta incorrecta)." +msgstr "El origen de la malla es inválido (ruta inválida)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (not a MeshInstance)." -msgstr "El modelo elegido no es correcto (al no ser un MeshInstance)." +msgstr "La malla elegida no es correcta (no es un MeshInstance)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (contains no Mesh resource)." -msgstr "El modelo elegido no es correcto (no contiene ningún recurso Mesh)." +msgstr "La malla elegida no es correcta (no contiene ningún recurso Mesh)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No surface source specified." -msgstr "Ninguna superficie de origen especificada." +msgstr "Ningún origen para la superficie especificado." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (invalid path)." -msgstr "La superficie de origen es incorrecta (ruta inválida)." +msgstr "El origen de la superficie es incorrecto (ruta inválida)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (no geometry)." -msgstr "La superficie de origen es inválida (sin geometrÃa)." +msgstr "El origen de la superficie no es correcto (sin geometrÃa)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (no faces)." -msgstr "La superficie de origen es inválida (sin caras)." +msgstr "El origen de la superficie no es correcto (sin caras)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Parent has no solid faces to populate." @@ -4236,15 +4126,15 @@ msgstr "La superficie padre no tiene caras solidas para poblar." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Couldn't map area." -msgstr "No se pudo mapear el area." +msgstr "No se pudo mapear el área." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Source Mesh:" -msgstr "Elige un modelo 3D:" +msgstr "Elige un origen de malla:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Target Surface:" -msgstr "Seleccioná una Superficie Objetivo:" +msgstr "Selecciona una Superficie Objetivo:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Populate Surface" @@ -4276,7 +4166,7 @@ msgstr "Eje Z" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh Up Axis:" -msgstr "Eje vertical del modelo:" +msgstr "Eje vertical de la malla:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Random Rotation:" @@ -4296,76 +4186,63 @@ msgstr "Rellenar" #: editor/plugins/navigation_mesh_editor_plugin.cpp msgid "Bake!" -msgstr "¡Quemar!" +msgstr "¡Calcular!" #: editor/plugins/navigation_mesh_editor_plugin.cpp -#, fuzzy msgid "Bake the navigation mesh." -msgstr "Crear modelo de navegación 3D" +msgstr "Pre-calcular la malla de navegación 3D." #: editor/plugins/navigation_mesh_editor_plugin.cpp -#, fuzzy msgid "Clear the navigation mesh." -msgstr "Crear modelo de navegación 3D" +msgstr "Vaciar malla de navegación 3D." #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Setting up Configuration..." msgstr "Estableciendo la Configuración..." #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Calculating grid size..." msgstr "Calculando tamaño de cuadrÃcula..." #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Creating heightfield..." -msgstr "Creando octree de luces" +msgstr "Creando octree de luces (\"heigfield\")..." #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Marking walkable triangles..." -msgstr "Cadenas traducibles…" +msgstr "Marcando triángulos transitables..." #: editor/plugins/navigation_mesh_generator.cpp msgid "Constructing compact heightfield..." -msgstr "" +msgstr "Construyendo heightfield compacto..." #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Eroding walkable area..." -msgstr "Erosión del área transitable..." +msgstr "Erosionando área transitable..." #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Partitioning..." -msgstr "Advertencia" +msgstr "Particionando..." #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Creating contours..." -msgstr "Creando octree de texturas" +msgstr "Creando contornos..." #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Creating polymesh..." -msgstr "Crear modelo 3D de contorno.." +msgstr "Crear malla 3D de contorno (\"polymesh\")..." #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Converting to native navigation mesh..." -msgstr "Crear modelo de navegación 3D" +msgstr "Convirtiendo a malla de navegación nativa..." #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Navigation Mesh Generator Setup:" -msgstr "Configuración del Generador de Malla de Navegación:" +msgstr "Configuración del Generador de Mallas de Navegación:" #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Parsing Geometry..." -msgstr "Leyendo geometrÃa" +msgstr "Analizando geometrÃa..." #: editor/plugins/navigation_mesh_generator.cpp msgid "Done!" @@ -4377,25 +4254,21 @@ msgstr "Crear polÃgono de navegación" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Generating AABB" -msgstr "Generar AABB" +msgstr "Generando AABB" #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Can only set point into a ParticlesMaterial process material" msgstr "" -"Solo se puede asignar el punto a un material procesado del tipo " -"ParticlesMaterial." +"Solo se puede asignar un punto a un material de procesado ParticlesMaterial" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Error loading image:" msgstr "Error al cargar la imagen:" #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "No pixels with transparency > 128 in image.." -msgstr "No hay pÃxeles con una transparencia mayor que 128 en la imagen.." +msgstr "No hay pÃxeles con transparencia > 128 en la imagen.." #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generate Visibility Rect" @@ -4411,9 +4284,8 @@ msgstr "Borrar máscara de emisión" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Particles" -msgstr "Vértice" +msgstr "PartÃculas" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generated Point Count:" @@ -4421,24 +4293,20 @@ msgstr "Conteo de puntos generados:" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Generation Time (sec):" -msgstr "Tiempo promedio (seg)" +msgstr "Tiempo de generación (seg):" #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Emission Mask" -msgstr "Establecer máscara de emisión" +msgstr "Máscara de emisión" #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Capture from Pixel" -msgstr "Crear desde escena" +msgstr "Capturar desde pÃxel" #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Emission Colors" -msgstr "Posiciones de emisión:" +msgstr "Colores de emisión" #: editor/plugins/particles_editor_plugin.cpp msgid "Node does not contain geometry." @@ -4465,65 +4333,55 @@ msgid "Generate AABB" msgstr "Generar AABB" #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Create Emission Points From Mesh" -msgstr "Crear emisor a partir de modelo" +msgstr "Crear puntos de emisión desde malla" #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Create Emission Points From Node" -msgstr "Crear emisor a partir de nodo" +msgstr "Crear puntos de emisión desde el nodo" #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emitter" msgstr "Crear emisor" #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Emission Points:" -msgstr "Posiciones de emisión:" +msgstr "Puntos de emisión:" #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Surface Points" -msgstr "Superficie %d" +msgstr "Puntos de la superficie" #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Surface Points+Normal (Directed)" -msgstr "Puntos de superficio + Normal (Dirigida)" +msgstr "Puntos de la superficie + Normal (Dirigida)" #: editor/plugins/particles_editor_plugin.cpp msgid "Volume" msgstr "Volumen" #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Emission Source: " -msgstr "Relleno de emisión:" +msgstr "Fuente de emisión: " #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Generate Visibility AABB" -msgstr "Generar AABB" +msgstr "Generar AABB de visibilidad" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" -msgstr "Borrar punto de curva" +msgstr "Borrar punto de la curva" #: editor/plugins/path_2d_editor_plugin.cpp -#, fuzzy msgid "Remove Out-Control from Curve" -msgstr "Mover Out-Control en Curva" +msgstr "Eliminar \"Out-Control\" de la Curva" #: editor/plugins/path_2d_editor_plugin.cpp -#, fuzzy msgid "Remove In-Control from Curve" -msgstr "Borrar punto de curva" +msgstr "Eliminar \"In-Control\" de la curva" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp -#, fuzzy msgid "Add Point to Curve" msgstr "Añadir punto a curva" @@ -4551,9 +4409,8 @@ msgstr "Mayús + arrastrar: Seleccionar puntos de control" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp -#, fuzzy msgid "Click: Add Point" -msgstr "Clic: Añadir punto" +msgstr "Click: Añadir punto" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp @@ -4586,22 +4443,19 @@ msgstr "Cerrar curva" #: editor/plugins/path_editor_plugin.cpp msgid "Curve Point #" -msgstr "Nº de punto en curva" +msgstr "Punto de curva #" #: editor/plugins/path_editor_plugin.cpp -#, fuzzy msgid "Set Curve Point Position" -msgstr "Establecer pos. de punto de curva" +msgstr "Establecer posición de punto de curva" #: editor/plugins/path_editor_plugin.cpp -#, fuzzy msgid "Set Curve In Position" -msgstr "Establecer pos. de entrada de curva" +msgstr "Establecer posición de entrada de curva" #: editor/plugins/path_editor_plugin.cpp -#, fuzzy msgid "Set Curve Out Position" -msgstr "Establecer pos. de salida de curva" +msgstr "Establecer posición de salida de curva" #: editor/plugins/path_editor_plugin.cpp msgid "Split Path" @@ -4609,17 +4463,15 @@ msgstr "Dividir ruta" #: editor/plugins/path_editor_plugin.cpp msgid "Remove Path Point" -msgstr "Quitar Punto de ruta" +msgstr "Quitar punto de ruta" #: editor/plugins/path_editor_plugin.cpp -#, fuzzy msgid "Remove Out-Control Point" -msgstr "Mover Out-Control en Curva" +msgstr "Eliminar punto \"Out-Control\"" #: editor/plugins/path_editor_plugin.cpp -#, fuzzy msgid "Remove In-Control Point" -msgstr "Mover In-Control en Curva" +msgstr "Eliminar punto \"In-Control\"" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create UV Map" @@ -4684,11 +4536,11 @@ msgstr "Limpiar UV" #: editor/plugins/polygon_2d_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap" -msgstr "Adherir a cuadrÃcula" +msgstr "Ajustar a cuadrÃcula" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Enable Snap" -msgstr "Adherir a cuadrÃcula" +msgstr "Habilitar fijado" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid" @@ -4716,6 +4568,22 @@ msgid "Resource clipboard is empty!" msgstr "¡El portapapeles de recursos está vacÃo!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Abrir en el editor" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Instancia:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Tipo:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Cargar recurso" @@ -4728,21 +4596,16 @@ msgid "Paste" msgstr "Pegar" #: editor/plugins/resource_preloader_editor_plugin.cpp -#, fuzzy msgid "ResourcePreloader" -msgstr "Ruta de recursos" +msgstr "Pre-cargador de Recursos (ResourcePreloader)" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Clear Recent Files" -msgstr "Reestablecer huesos" +msgstr "Limpiar lista archivos recientes" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Close and save changes?" -msgstr "" -"¿Cerrar y guardar cambios?\n" -"\"" +msgstr "¿Cerrar y guardar cambios?" #: editor/plugins/script_editor_plugin.cpp msgid "Error while saving theme" @@ -4773,9 +4636,8 @@ msgid " Class Reference" msgstr " Referencia de clase" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Sort" -msgstr "Ordenar:" +msgstr "Ordenar" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp @@ -4814,14 +4676,12 @@ msgid "Soft Reload Script" msgstr "Recargar parcialmente el script" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Copy Script Path" -msgstr "Copiar ruta" +msgstr "Copiar ruta del script" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Show In File System" -msgstr "SistDeArchivos" +msgstr "Mostrar en sistema de archivos" #: editor/plugins/script_editor_plugin.cpp msgid "History Prev" @@ -4848,9 +4708,8 @@ msgid "Close Docs" msgstr "Cerrar documentación" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Close All" -msgstr "Cerrar" +msgstr "Cerrar todo" #: editor/plugins/script_editor_plugin.cpp msgid "Close Other Tabs" @@ -4861,9 +4720,8 @@ msgid "Run" msgstr "Ejecutar" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Toggle Scripts Panel" -msgstr "Añadir/quitar favorito" +msgstr "Alternar panel de scripts" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -4897,14 +4755,12 @@ msgid "Keep Debugger Open" msgstr "Mantener el depurador abierto" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Debug with external editor" -msgstr "Abrir en el editor" +msgstr "Depurar en editor externo" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation" -msgstr "Buscar en la documentación de referencia." +msgstr "Abrir documentación online de Godot" #: editor/plugins/script_editor_plugin.cpp msgid "Search the class hierarchy." @@ -4923,9 +4779,8 @@ msgid "Go to next edited document." msgstr "Ir a siguiente documento editado." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Discard" -msgstr "Discreto" +msgstr "Descartar" #: editor/plugins/script_editor_plugin.cpp msgid "Create Script" @@ -4959,19 +4814,16 @@ msgstr "" "pertenecen está cargada" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Only resources from filesystem can be dropped." -msgstr "Solo se pueden soltar recursos del sistema." +msgstr "Sólo se pueden arrastrar/soltar recursos del sistema de archivos." #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Pick Color" -msgstr "Color" +msgstr "Seleccionar color" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Convert Case" -msgstr "Convirtiendo imágenes" +msgstr "Convertir Máy/Min" #: editor/plugins/script_text_editor.cpp msgid "Uppercase" @@ -5002,9 +4854,8 @@ msgid "Select All" msgstr "Seleccionar todo" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Delete Line" -msgstr "Eliminar punto" +msgstr "Eliminar lÃnea" #: editor/plugins/script_text_editor.cpp msgid "Indent Left" @@ -5019,23 +4870,20 @@ msgid "Toggle Comment" msgstr "Des/activar comentario" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Clonar hacia abajo" - -#: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Fold/Unfold Line" -msgstr "Desplegar LÃnea" +msgstr "Plegar/Desplegar lÃnea" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Fold All Lines" -msgstr "Plegar Todas las LÃneas" +msgstr "Plegar todas las lÃneas" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Unfold All Lines" -msgstr "Desplegar Todas las LÃneas" +msgstr "Desplegar todas las lÃneas" + +#: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Clonar hacia abajo" #: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" @@ -5050,9 +4898,8 @@ msgid "Convert Indent To Spaces" msgstr "Convertir Indentación a Espacios" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Convert Indent To Tabs" -msgstr "Convertir Indentación a Tabuladores" +msgstr "Convertir indentación a tabuladores" #: editor/plugins/script_text_editor.cpp msgid "Auto Indent" @@ -5065,7 +4912,7 @@ msgstr "Des/activar «breakpoint»" #: editor/plugins/script_text_editor.cpp msgid "Remove All Breakpoints" -msgstr "Desactivar todos los «breakpoints»" +msgstr "Borrar todos los «breakpoints»" #: editor/plugins/script_text_editor.cpp msgid "Goto Next Breakpoint" @@ -5076,14 +4923,12 @@ msgid "Goto Previous Breakpoint" msgstr "Ir al «breakpoint» anterior" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Convert To Uppercase" -msgstr "Convertir a…" +msgstr "Convertir a mayúsculas" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Convert To Lowercase" -msgstr "Convertir a…" +msgstr "Convertir a minúsculas" #: editor/plugins/script_text_editor.cpp msgid "Find Previous" @@ -5107,7 +4952,7 @@ msgstr "Ayuda contextual" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" -msgstr "Shader" +msgstr "\"Shader\"" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Scalar Constant" @@ -5182,9 +5027,8 @@ msgid "Change Comment" msgstr "Cambiar ComentarÃo" #: editor/plugins/shader_graph_editor_plugin.cpp -#, fuzzy msgid "Add/Remove to Color Ramp" -msgstr "Añadir/quitar a/de rampa de color" +msgstr "Añadir/quitar de rampa de color" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Add/Remove to Curve Map" @@ -5200,40 +5044,39 @@ msgstr "Cambiar Nombre de Entrada" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Connect Graph Nodes" -msgstr "Conectar Nodos de Gráfico" +msgstr "Conectar Nodos Gráficos" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Disconnect Graph Nodes" -msgstr "Desconectar Nodo de Gráfico" +msgstr "Desconectar Nodos Gráficos" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Remove Shader Graph Node" -msgstr "Quitar Nodo de Gráfico de Shaders" +msgstr "Borrar Nodo Gráfico de Shader" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Move Shader Graph Node" -msgstr "Mover Nodo de Gráfico de Shaders" +msgstr "Mover Nodo Gráfico de Shader" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Duplicate Graph Node(s)" -msgstr "Duplicar Nodo(s) de Gráfico" +msgstr "Duplicar Nodo(s) Gráfico" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Delete Shader Graph Node(s)" -msgstr "Quitar Nodo(s) de Gráfico de Shaders" +msgstr "Borrar Nodo(s) Gráfico(s) de Shader" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Error: Cyclic Connection Link" -msgstr "Error: Link de Conección CÃclico" +msgstr "Error: Link de Conexión CÃclico" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Error: Missing Input Connections" -msgstr "Error: Conecciones de Entrada Faltantes" +msgstr "Error: Conexiones de Entrada Faltantes" #: editor/plugins/shader_graph_editor_plugin.cpp -#, fuzzy msgid "Add Shader Graph Node" -msgstr "Añadir nodo de gráficos de sombreador" +msgstr "Añadir nodo gráfico de Shader" #: editor/plugins/spatial_editor_plugin.cpp msgid "Orthogonal" @@ -5264,14 +5107,12 @@ msgid "View Plane Transform." msgstr "Ver transformación en plano." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Scaling: " -msgstr "Escala:" +msgstr "Escalado: " #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Translating: " -msgstr "Traducciones:" +msgstr "Traduciendo: " #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotating %s degrees." @@ -5279,41 +5120,35 @@ msgstr "Girando %s grados." #: editor/plugins/spatial_editor_plugin.cpp msgid "Keying is disabled (no key inserted)." -msgstr "Poner claves está desactivado (no se insertaron claves)." +msgstr "Insertar claves está desactivado (no se insertaron claves)." #: editor/plugins/spatial_editor_plugin.cpp msgid "Animation Key Inserted." msgstr "Clave de animación insertada." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Objects Drawn" msgstr "Objetos dibujados" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Material Changes" -msgstr "Actualizar cambios" +msgstr "Cambios del material" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Shader Changes" -msgstr "Actualizar cambios" +msgstr "Cambios del shader" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Surface Changes" -msgstr "Actualizar cambios" +msgstr "Cambios de superficie" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Draw Calls" msgstr "Llamadas de dibujado" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Vertices" -msgstr "Vértice" +msgstr "Vértices" #: editor/plugins/spatial_editor_plugin.cpp msgid "FPS" @@ -5392,94 +5227,82 @@ msgid "Display Overdraw" msgstr "Mostrar superposiciones" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Display Unshaded" -msgstr "Mostrar sin sombras" +msgstr "Mostrar sin sombra" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "View Environment" -msgstr "Entorno" +msgstr "Ver entorno" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "View Gizmos" -msgstr "Gizmos" +msgstr "Ver gizmos" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Information" msgstr "Ver información" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "View FPS" -msgstr "Ver Archivos" +msgstr "Ver FPS" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Half Resolution" -msgstr "Escalar selección" +msgstr "Media resolución" #: editor/plugins/spatial_editor_plugin.cpp msgid "Audio Listener" msgstr "Oyente de Audio" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Doppler Enable" -msgstr "Activar" +msgstr "Activar Doppler" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Freelook Left" msgstr "Vista libre izquierda" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Freelook Right" msgstr "Vista libre derecha" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Freelook Forward" -msgstr "Avanzar" +msgstr "Vista libre frente" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Freelook Backwards" -msgstr "Hacia atrás" +msgstr "Vista libre atrás" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Freelook Up" -msgstr "Vista libre superior" +msgstr "Vista libre arriba" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Freelook Down" -msgstr "Rueda hacia abajo." +msgstr "Vista libre abajo" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Freelook Speed Modifier" -msgstr "Modificador de velocidad de la vista libre" +msgstr "Modificador de velocidad de \"vista libre\"" #: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Ventana de transformación" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Select Mode (Q)" -msgstr "Modo de selección" +msgstr "Modo de selección (Q)" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "" "Drag: Rotate\n" "Alt+Drag: Move\n" "Alt+RMB: Depth list selection" -msgstr "Alt+Click Der.: Selección en depth list" +msgstr "" +"Arrastrar: Rotar\n" +"Alt + Arrastrar: Mover\n" +"Alt + Click derecho: Selección en la lista de superposición" #: editor/plugins/spatial_editor_plugin.cpp msgid "Move Mode (W)" @@ -5498,14 +5321,12 @@ msgid "Local Coords" msgstr "Coordenadas locales" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Local Space Mode (%s)" -msgstr "Modo escalado (R)" +msgstr "Modo de espacio local (%s)" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Mode (%s)" -msgstr "Modo de fijado:" +msgstr "Modo de ajuste (%s)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom View" @@ -5540,42 +5361,36 @@ msgid "Insert Animation Key" msgstr "Insertar clave de animación" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Focus Origin" -msgstr "Ver origen" +msgstr "Enfocar origen" #: editor/plugins/spatial_editor_plugin.cpp msgid "Focus Selection" -msgstr "Seleccionar" +msgstr "Enfocar selección" #: editor/plugins/spatial_editor_plugin.cpp msgid "Align Selection With View" msgstr "Alinear selección con visor" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Tool Select" msgstr "Seleccionar" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Tool Move" msgstr "Mover" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Tool Rotate" -msgstr "Ctrl: Rotar" +msgstr "Rotar" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Tool Scale" -msgstr "Escala:" +msgstr "Escalar" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Toggle Freelook" -msgstr "Modo pantalla completa" +msgstr "Alternar vista libre" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform" @@ -5583,7 +5398,7 @@ msgstr "Transformar" #: editor/plugins/spatial_editor_plugin.cpp msgid "Configure Snap.." -msgstr "Configurar fijado.." +msgstr "Configurar ajuste.." #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Dialog.." @@ -5628,23 +5443,23 @@ msgstr "Ajustes" #: editor/plugins/spatial_editor_plugin.cpp msgid "Skeleton Gizmo visibility" -msgstr "" +msgstr "Visibilidad de Gizmo esqueleto" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Settings" -msgstr "Ajustes de fijado" +msgstr "Configuración de fijado" #: editor/plugins/spatial_editor_plugin.cpp msgid "Translate Snap:" -msgstr "Fijar desplazamiento:" +msgstr "Ajuste de desplazamiento:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotate Snap (deg.):" -msgstr "Fijar rotación (grados):" +msgstr "Ajuste de rotación (grados):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale Snap (%):" -msgstr "Fijar escala (%):" +msgstr "Ajuste de escala (%):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Viewport Settings" @@ -5692,11 +5507,11 @@ msgstr "Posterior" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "ERROR: Couldn't load frame resource!" -msgstr "ERROR: ¡No se pudo cargar el recurso de cuadros!" +msgstr "ERROR: ¡No se pudo cargar el recurso de fotogramas!" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" -msgstr "Añadir cuadro" +msgstr "Añadir fotograma" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Resource clipboard is empty or not a texture!" @@ -5704,7 +5519,7 @@ msgstr "¡El portapapeles de recursos esta vacÃo o no es una textura!" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Paste Frame" -msgstr "Pegar cuadro" +msgstr "Pegar fotograma" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Empty" @@ -5736,7 +5551,7 @@ msgstr "Repetir" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Animation Frames" -msgstr "Cuadros de animación" +msgstr "Fotogramas de animación" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -5747,33 +5562,28 @@ msgid "Insert Empty (After)" msgstr "Insertar vacÃo (después)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Move (Before)" -msgstr "Borrar nodos" +msgstr "Mover (Antes)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Move (After)" -msgstr "Mover a la izquierda" +msgstr "Mover (Después)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "SpriteFrames" -msgstr "Frames del Stack" +msgstr "Fotogramas del sprite" #: editor/plugins/style_box_editor_plugin.cpp msgid "StyleBox Preview:" msgstr "Vista previa de StyleBox:" #: editor/plugins/style_box_editor_plugin.cpp -#, fuzzy msgid "StyleBox" -msgstr "Estilo" +msgstr "Caja de estilos" #: editor/plugins/texture_region_editor_plugin.cpp -#, fuzzy msgid "Set Region Rect" -msgstr "Setear region_rect" +msgstr "Establecer rectángulo de región" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Snap Mode:" @@ -5785,11 +5595,11 @@ msgstr "<Ninguno>" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Pixel Snap" -msgstr "Adherir a pÃxeles" +msgstr "Ajustar a pÃxeles" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Grid Snap" -msgstr "Adherir a cuadrÃcula" +msgstr "Ajustar a cuadrÃcula" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Auto Slice" @@ -5836,14 +5646,12 @@ msgid "Remove Item" msgstr "Remover Item" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove All Items" -msgstr "Quitar elementos de clases" +msgstr "Quitar todos los elementos" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove All" -msgstr "Quitar" +msgstr "Quitar todos" #: editor/plugins/theme_editor_plugin.cpp msgid "Edit theme.." @@ -5870,9 +5678,8 @@ msgid "Create Empty Editor Template" msgstr "Crear plantilla de editor vacÃa" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Create From Current Editor Theme" -msgstr "Crear plantilla de editor vacÃa" +msgstr "Crear desde el tema actual del editor" #: editor/plugins/theme_editor_plugin.cpp msgid "CheckBox Radio1" @@ -5922,11 +5729,6 @@ msgstr "Tab 2" msgid "Tab 3" msgstr "Tab 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Tipo:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Tipo de datos:" @@ -5948,33 +5750,28 @@ msgid "Color" msgstr "Color" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Theme" -msgstr "Guardar tema" +msgstr "Tema" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Erase Selection" -msgstr "Eliminar selección" +msgstr "Borrar selección" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint TileMap" -msgstr "Pintar TileMap" +msgstr "Dibujar TileMap" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Line Draw" -msgstr "Lineal" +msgstr "Dibujar lÃnea" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rectangle Paint" -msgstr "Rectángulo de pintura" +msgstr "Dibujar Rectángulo" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Bucket Fill" -msgstr "Cubo" +msgstr "Cubo de relleno" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase TileMap" @@ -6001,9 +5798,8 @@ msgid "Mirror Y" msgstr "Voltear verticalmente" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Paint Tile" -msgstr "Pintar TileMap" +msgstr "Dibujar Tile" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" @@ -6039,12 +5835,11 @@ msgstr "¿Crear desde escena?" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Merge from scene?" -msgstr "¿Mergear desde escena?" +msgstr "¿Mezclar desde escena?" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tile Set" -msgstr "TileSet.." +msgstr "\"Tile Set\"" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from Scene" @@ -6059,59 +5854,57 @@ msgid "Error" msgstr "Error" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Autotiles" -msgstr "Autotrocear" +msgstr "\"Autotiles\"" #: editor/plugins/tile_set_editor_plugin.cpp msgid "" "Select sub-tile to use as icon, this will be also used on invalid autotile " "bindings." msgstr "" +"Seleccione sub-tile para utilizar como icono, éste se utilizará también en " +"enlazados automáticos no válidos." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" "LMB: set bit on.\n" "RMB: set bit off." msgstr "" +"Click izquierdo: habilitar bit.\n" +"Click derecho: deshabilitar bit." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Select current edited sub-tile." -msgstr "Guardar el recurso editado actualmente." +msgstr "Guardar el sub-tile editado actualmente." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select sub-tile to change its priority." -msgstr "" +msgstr "Selecciona sub-tile para cambiar su prioridad." #: editor/progress_dialog.cpp scene/gui/dialogs.cpp msgid "Cancel" msgstr "Cancelar" #: editor/project_export.cpp -#, fuzzy msgid "Runnable" -msgstr "Activar" +msgstr "Ejecutable" #: editor/project_export.cpp -#, fuzzy msgid "Delete patch '%s' from list?" -msgstr "Eliminar entrada" +msgstr "¿Eliminar patch '%s' de la lista?" #: editor/project_export.cpp -#, fuzzy msgid "Delete preset '%s'?" -msgstr "¿Quieres eliminar los archivos seleccionados?" +msgstr "¿Eliminar preajuste '%s'?" #: editor/project_export.cpp -#, fuzzy msgid "Export templates for this platform are missing/corrupted: " -msgstr "Faltan las siguientes plantillas de exportación para esta plataforma:" +msgstr "" +"Las plantillas de exportación para esta plataforma faltan/están corruptas: " #: editor/project_export.cpp -#, fuzzy msgid "Presets" -msgstr "Ajuste…" +msgstr "Preajustes" #: editor/project_export.cpp editor/project_settings_editor.cpp msgid "Add.." @@ -6122,121 +5915,99 @@ msgid "Resources" msgstr "Recursos" #: editor/project_export.cpp -#, fuzzy msgid "Export all resources in the project" -msgstr "Exportar todos los recursos en el proyecto." +msgstr "Exportar todos los recursos del proyecto" #: editor/project_export.cpp -#, fuzzy msgid "Export selected scenes (and dependencies)" -msgstr "Exportar los recursos seleccionado (incluyendo dependencias)." +msgstr "Exportar las escenas seleccionadas (incluyendo dependencias)" #: editor/project_export.cpp -#, fuzzy msgid "Export selected resources (and dependencies)" -msgstr "Exportar los recursos seleccionado (incluyendo dependencias)." +msgstr "Exportar los recursos seleccionado (incluyendo dependencias)" #: editor/project_export.cpp msgid "Export Mode:" msgstr "Modo de exportación:" #: editor/project_export.cpp -#, fuzzy msgid "Resources to export:" msgstr "Recursos a exportar:" #: editor/project_export.cpp -#, fuzzy msgid "" "Filters to export non-resource files (comma separated, e.g: *.json, *.txt)" msgstr "" "Filtros para exportar archivos que no son recursos (separados por comas, ej: " -"*.json, *.txt):" +"*.json, *.txt)" #: editor/project_export.cpp -#, fuzzy msgid "" "Filters to exclude files from project (comma separated, e.g: *.json, *.txt)" msgstr "" "Filtros para excluir de la exportación (separados por comas, ej: *.json, *." -"txt):" +"txt)" #: editor/project_export.cpp -#, fuzzy msgid "Patches" -msgstr "Coincidencias:" +msgstr "Exportaciones previas" #: editor/project_export.cpp -#, fuzzy msgid "Make Patch" -msgstr "Ruta de destino:" +msgstr "Hacer \"Patch\"" #: editor/project_export.cpp -#, fuzzy msgid "Features" -msgstr "Textura" +msgstr "CaracterÃsticas" #: editor/project_export.cpp -#, fuzzy msgid "Custom (comma-separated):" msgstr "Personalizado (separado por comas):" #: editor/project_export.cpp -#, fuzzy msgid "Feature List:" -msgstr "Lista de métodos:" +msgstr "Lista de caracterÃsticas:" #: editor/project_export.cpp msgid "Export PCK/Zip" msgstr "Exportar PCK/Zip" #: editor/project_export.cpp -#, fuzzy msgid "Export templates for this platform are missing:" -msgstr "Faltan las siguientes plantillas de exportación para esta plataforma:" +msgstr "Faltan plantillas de exportación para esta plataforma:" #: editor/project_export.cpp -#, fuzzy msgid "Export templates for this platform are missing/corrupted:" -msgstr "Faltan las siguientes plantillas de exportación para esta plataforma:" +msgstr "" +"Las plantillas de exportación para esta plataforma faltan/están corruptas:" #: editor/project_export.cpp -#, fuzzy msgid "Export With Debug" -msgstr "Exportar Tile Set" +msgstr "Exportar con depuración" #: editor/project_manager.cpp -#, fuzzy msgid "The path does not exist." -msgstr "El archivo existe." +msgstr "La ruta no existe." #: editor/project_manager.cpp -#, fuzzy msgid "Please choose a 'project.godot' file." -msgstr "¡Prueba exportando fuera de la carpeta del proyecto!" +msgstr "Por favor elija un archivo 'project.godot'." #: editor/project_manager.cpp -#, fuzzy msgid "Please choose an empty folder." -msgstr "¡Prueba exportando fuera de la carpeta del proyecto!" - -#: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" -"Por favor, elige un directorio que no contenga un archivo 'project.godot'." +msgstr "Por favor elija una carpeta vacÃa." #: editor/project_manager.cpp msgid "Imported Project" msgstr "Proyecto importado" #: editor/project_manager.cpp -#, fuzzy msgid "Couldn't create folder." msgstr "No se pudo crear la carpeta." #: editor/project_manager.cpp msgid "There is already a folder in this path with the specified name." -msgstr "" +msgstr "Ya hay una carpeta en esta ruta con ese nombre." #: editor/project_manager.cpp msgid "It would be a good idea to name your project." @@ -6247,33 +6018,28 @@ msgid "Invalid project path (changed anything?)." msgstr "La ruta del proyecto no es correcta (¿has cambiado algo?)." #: editor/project_manager.cpp -#, fuzzy -msgid "Couldn't get project.godot in project path." -msgstr "No se pudo crear engine.cfg en la ruta de proyecto." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" +"No se pudo cargar project.godot desde la ruta de proyecto (error %d). La " +"ruta no existe o está corrupta." #: editor/project_manager.cpp -#, fuzzy msgid "Couldn't edit project.godot in project path." -msgstr "No se pudo crear engine.cfg en la ruta de proyecto." +msgstr "No se pudo editar project.godot en la ruta del proyecto." #: editor/project_manager.cpp -#, fuzzy msgid "Couldn't create project.godot in project path." -msgstr "No se pudo crear engine.cfg en la ruta de proyecto." +msgstr "No se pudo crear project.godot en la ruta del proyecto." #: editor/project_manager.cpp msgid "The following files failed extraction from package:" msgstr "Los siguientes archivos no se pudieron extraer del paquete:" #: editor/project_manager.cpp -#, fuzzy msgid "Rename Project" -msgstr "Proyecto sin nombre" - -#: editor/project_manager.cpp -#, fuzzy -msgid "Couldn't get project.godot in the project path." -msgstr "No se pudo crear engine.cfg en la ruta de proyecto." +msgstr "Renombrar proyecto" #: editor/project_manager.cpp msgid "New Game Project" @@ -6284,34 +6050,30 @@ msgid "Import Existing Project" msgstr "Importar proyecto existente" #: editor/project_manager.cpp -#, fuzzy msgid "Import & Edit" -msgstr "Importar y abrir" +msgstr "Importar y editar" #: editor/project_manager.cpp msgid "Create New Project" msgstr "Crear proyecto nuevo" #: editor/project_manager.cpp -#, fuzzy msgid "Create & Edit" -msgstr "Crear emisor" +msgstr "Crear y editar" #: editor/project_manager.cpp msgid "Install Project:" msgstr "Instalar proyecto:" #: editor/project_manager.cpp -#, fuzzy msgid "Install & Edit" -msgstr "Instalar" +msgstr "Instalar y editar" #: editor/project_manager.cpp msgid "Project Name:" msgstr "Nombre del proyecto:" #: editor/project_manager.cpp -#, fuzzy msgid "Create folder" msgstr "Crear carpeta" @@ -6328,32 +6090,29 @@ msgid "Unnamed Project" msgstr "Proyecto sin nombre" #: editor/project_manager.cpp -#, fuzzy msgid "Can't open project" -msgstr "Conectar.." +msgstr "No se puede abrir proyecto" #: editor/project_manager.cpp msgid "Are you sure to open more than one project?" msgstr "¿Seguro que quieres abrir más de un proyecto?" #: editor/project_manager.cpp -#, fuzzy msgid "" "Can't run project: no main scene defined.\n" "Please edit the project and set the main scene in \"Project Settings\" under " "the \"Application\" category." msgstr "" -"No se ha definido ninguna escena principal, ¿quieres elegir alguna?\n" -"Es posible cambiarla más tarde en «Ajustes del proyecto» bajo la categorÃa " -"«aplicación»." +"No hay una escena principal definida para ejecutar el proyecto.\n" +"Por favor elija la escena principal en \"Ajustes del proyecto\" en la " +"categorÃa \"Aplicación\"." #: editor/project_manager.cpp -#, fuzzy msgid "" "Can't run project: Assets need to be imported.\n" "Please edit the project to trigger the initial import." msgstr "" -"No se puede ejecutar el proyecto: Los assets necesitan ser importados.\n" +"No se puede ejecutar el proyecto: los assets necesitan ser importados.\n" "Por favor, edita el proyecto para activar el importado inicial." #: editor/project_manager.cpp @@ -6404,31 +6163,27 @@ msgid "New Project" msgstr "Proyecto nuevo" #: editor/project_manager.cpp -#, fuzzy msgid "Templates" -msgstr "Remover Item" +msgstr "Plantillas" #: editor/project_manager.cpp msgid "Exit" msgstr "Salir" #: editor/project_manager.cpp -#, fuzzy msgid "Restart Now" -msgstr "Reiniciar (s):" +msgstr "Reiniciar ahora" #: editor/project_manager.cpp -#, fuzzy msgid "Can't run project" -msgstr "Conectar.." +msgstr "No se puede ejecutar el proyecto" #: editor/project_manager.cpp -#, fuzzy msgid "" "You don't currently have any projects.\n" "Would you like to explore the official example projects in the Asset Library?" msgstr "" -"Actualmente no tiene ningún proyecto.\n" +"Ahora mismo no tiene ningún proyecto.\n" "¿Le gustarÃa explorar los proyectos ejemplo oficiales del Asset Library?" #: editor/project_settings_editor.cpp @@ -6520,32 +6275,28 @@ msgid "Button 9" msgstr "Botón 9" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Joypad Axis Index:" -msgstr "Ãndice de ejes del mando:" +msgstr "Ãndice de eje del mando:" #: editor/project_settings_editor.cpp msgid "Axis" msgstr "Eje" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Joypad Button Index:" -msgstr "Ãndice de botones del mando:" +msgstr "Ãndice de boton del mando:" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Erase Input Action" -msgstr "Borrar evento de acción de entrada" +msgstr "Borrar \"Input Action\"" #: editor/project_settings_editor.cpp msgid "Erase Input Action Event" msgstr "Borrar evento de acción de entrada" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Add Event" -msgstr "Añadir elemento vacÃo" +msgstr "Añadir evento" #: editor/project_settings_editor.cpp msgid "Device" @@ -6576,38 +6327,32 @@ msgid "Wheel Down." msgstr "Rueda hacia abajo." #: editor/project_settings_editor.cpp -#, fuzzy msgid "Add Global Property" -msgstr "Añadir propiedad «Getter»" +msgstr "Añadir propiedad global" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Select a setting item first!" -msgstr "¡Selecciona un item primero!" +msgstr "¡Selecciona un Ãtem primero!" #: editor/project_settings_editor.cpp -#, fuzzy msgid "No property '%s' exists." -msgstr "Propiedad:" +msgstr "No existe la propiedad '%s'." #: editor/project_settings_editor.cpp msgid "Setting '%s' is internal, and it can't be deleted." msgstr "El ajuste '%s' es interno y no puede ser eliminado." #: editor/project_settings_editor.cpp -#, fuzzy msgid "Delete Item" -msgstr "Eliminar entrada" +msgstr "Eliminar elemento" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Can't contain '/' or ':'" -msgstr "No se puede conectar al host:" +msgstr "No puede contener '/' o ':'" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Already existing" -msgstr "Des/activar persistencia" +msgstr "Ya existe" #: editor/project_settings_editor.cpp msgid "Add Input Action" @@ -6622,7 +6367,6 @@ msgid "Settings saved OK." msgstr "Los ajustes se han guardado correctamente." #: editor/project_settings_editor.cpp -#, fuzzy msgid "Override for Feature" msgstr "Sobreescribir para esta caracterÃstica" @@ -6655,19 +6399,16 @@ msgid "Remove Resource Remap Option" msgstr "Quitar opción de remapeo de recursos" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Changed Locale Filter" -msgstr "Cambiar tiempo de mezcla" +msgstr "Cambiar filtro de localización" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Changed Locale Filter Mode" -msgstr "Modo de Filtro del Locale Cambiado" +msgstr "Modo de filtro de localización cambiado" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Project Settings (project.godot)" -msgstr "Ajustes de proyecto (engine.cfg)" +msgstr "Ajustes del proyecto (project.godot)" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "General" @@ -6678,9 +6419,8 @@ msgid "Property:" msgstr "Propiedad:" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Override For.." -msgstr "Sobreescribir para.." +msgstr "Sobre escribir por.." #: editor/project_settings_editor.cpp msgid "Input Map" @@ -6727,38 +6467,32 @@ msgid "Locale" msgstr "Idioma" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Locales Filter" -msgstr "Filtrado de imágenes:" +msgstr "Filtro de localizaciones" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show all locales" -msgstr "Crear huesos" +msgstr "Mostrar todas las localizaciones" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show only selected locales" -msgstr "Mostrar solo Las Configuraciones Regionales Seleccionadas" +msgstr "Mostrar solo las configuraciones regionales seleccionadas" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Filter mode:" -msgstr "Filtros" +msgstr "Modo de filtrado:" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Locales:" -msgstr "Idioma" +msgstr "Idiomas:" #: editor/project_settings_editor.cpp msgid "AutoLoad" msgstr "AutoLoad" #: editor/property_editor.cpp -#, fuzzy msgid "Pick a Viewport" -msgstr "1 visor" +msgstr "Selecciona un visor" #: editor/property_editor.cpp msgid "Ease In" @@ -6793,45 +6527,38 @@ msgid "Assign" msgstr "Asignar" #: editor/property_editor.cpp -#, fuzzy msgid "Select Node" -msgstr "Selecciona un nodo" +msgstr "Seleccionar nodo" #: editor/property_editor.cpp -#, fuzzy msgid "New Script" -msgstr "Script siguiente" +msgstr "Nuevo script" #: editor/property_editor.cpp msgid "New %s" -msgstr "" +msgstr "Nuevo %s" #: editor/property_editor.cpp -#, fuzzy msgid "Make Unique" -msgstr "Crear huesos" +msgstr "Hacer único" #: editor/property_editor.cpp -#, fuzzy msgid "Show in File System" -msgstr "SistDeArchivos" +msgstr "Mostrar en el sistema de archivos" #: editor/property_editor.cpp -#, fuzzy msgid "Convert To %s" -msgstr "Convertir a.." +msgstr "Convertir a %s" #: editor/property_editor.cpp msgid "Error loading file: Not a resource!" msgstr "Error al cargar el archivo: ¡No es un recurso!" #: editor/property_editor.cpp -#, fuzzy msgid "Selected node is not a Viewport!" -msgstr "Selecciona nodos a importar" +msgstr "¡El nodo seleccionado no es un visor!" #: editor/property_editor.cpp -#, fuzzy msgid "Pick a Node" msgstr "Selecciona un nodo" @@ -6844,9 +6571,8 @@ msgid "On" msgstr "Activado" #: editor/property_editor.cpp -#, fuzzy msgid "[Empty]" -msgstr "Añadir elemento vacÃo" +msgstr "[VacÃo]" #: editor/property_editor.cpp modules/visual_script/visual_script_editor.cpp msgid "Set" @@ -6861,14 +6587,12 @@ msgid "Select Property" msgstr "Seleccionar Propiedad" #: editor/property_selector.cpp -#, fuzzy msgid "Select Virtual Method" -msgstr "Modo de selección" +msgstr "Seleccionar método virtual" #: editor/property_selector.cpp -#, fuzzy msgid "Select Method" -msgstr "Modo de selección" +msgstr "Seleccionar método" #: editor/pvrtc_compress.cpp msgid "Could not execute PVRTC tool:" @@ -6961,7 +6685,6 @@ msgid "Delete Node(s)?" msgstr "¿Quieres borrar los nodos?" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Can not perform with the root node." msgstr "No se puede efectuar con el nodo raÃz." @@ -7018,18 +6741,13 @@ msgid "Error duplicating scene to save it." msgstr "Error al duplicar escena para guardarla." #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Sub-Resources" -msgstr "Recursos:" +msgstr "Sub-recursos" #: editor/scene_tree_dock.cpp msgid "Clear Inheritance" msgstr "Limpiar heredado" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Abrir en el editor" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Borrar nodos" @@ -7047,14 +6765,12 @@ msgid "Change Type" msgstr "Cambiar tipo" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Attach Script" -msgstr "Añadir script" +msgstr "Adjuntar script" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Clear Script" -msgstr "Crear script" +msgstr "Quitar script" #: editor/scene_tree_dock.cpp msgid "Merge From Scene" @@ -7065,9 +6781,8 @@ msgid "Save Branch as Scene" msgstr "Guardar Rama como Escena" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Copy Node Path" -msgstr "Copiar ruta" +msgstr "Copiar ruta del nodo" #: editor/scene_tree_dock.cpp msgid "Delete (No Confirm)" @@ -7086,29 +6801,24 @@ msgstr "" "existe ningún nodo raÃz." #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Filter nodes" -msgstr "Filtros" +msgstr "Filtrar nodos" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Attach a new or existing script for the selected node." -msgstr "Crear un nuevo script para el nodo seleccionado." +msgstr "Adjuntar un script nuevo o existente al nodo seleccionado." #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Clear a script for the selected node." -msgstr "Crear un nuevo script para el nodo seleccionado." +msgstr "Borra el script del nodo seleccionado." #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Remote" -msgstr "Quitar" +msgstr "Remoto" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Local" -msgstr "Idioma" +msgstr "Local" #: editor/scene_tree_dock.cpp msgid "Clear Inheritance? (No Undo!)" @@ -7131,16 +6841,14 @@ msgid "Node configuration warning:" msgstr "Alerta de configuración de nodos:" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "" "Node has connection(s) and group(s)\n" "Click to show signals dock." msgstr "" -"El nodo tiene conexion(es) y grupo(s)\n" +"El nodo tiene conexión/es y grupo/s\n" "Haz click para mostrar el panel de señales." #: editor/scene_tree_editor.cpp -#, fuzzy msgid "" "Node has connections.\n" "Click to show signals dock." @@ -7157,13 +6865,8 @@ msgstr "" "Click para mostrar el panel de grupos." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "Instancia:" - -#: editor/scene_tree_editor.cpp -#, fuzzy msgid "Open script" -msgstr "Script siguiente" +msgstr "Abrir script" #: editor/scene_tree_editor.cpp msgid "" @@ -7182,9 +6885,8 @@ msgstr "" "Haz click para hacerlos seleccionables" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Toggle Visibility" -msgstr "Act/Desact. Espacial Visible" +msgstr "Alternar visibilidad" #: editor/scene_tree_editor.cpp msgid "Invalid node name, the following characters are not allowed:" @@ -7208,19 +6910,16 @@ msgid "Select a Node" msgstr "Selecciona un nodo" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Error loading template '%s'" -msgstr "Error al cargar la imagen:" +msgstr "Error al cargar la plantilla '%s'" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Error - Could not create script in filesystem." -msgstr "No se puede crear el script en el sistema de archivos." +msgstr "Error - No se pudo crear script en el sistema." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Error loading script from %s" -msgstr "Error al cargar escena desde %s" +msgstr "Error al cargar script desde %s" #: editor/script_create_dialog.cpp msgid "N/A" @@ -7243,90 +6942,76 @@ msgid "Directory of the same name exists" msgstr "Ya existe un directorio con el mismo nombre" #: editor/script_create_dialog.cpp -#, fuzzy msgid "File exists, will be reused" -msgstr "El archivo ya existe, ¿quieres sobreescribirlo?" +msgstr "El archivo ya existe, será reutilizado" #: editor/script_create_dialog.cpp msgid "Invalid extension" msgstr "La extensión no es correcta" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Wrong extension chosen" msgstr "Extensión seleccionada errónea" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid Path" -msgstr "Ruta incorrecta." +msgstr "Ruta inválida" #: editor/script_create_dialog.cpp msgid "Invalid class name" msgstr "El nombre de clase no es correcto" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid inherited parent name or path" -msgstr "El nombre de la propiedad Ãndice no es correcto." +msgstr "Nombre heredado o ruta inválida" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script valid" -msgstr "Script" +msgstr "Script válido" #: editor/script_create_dialog.cpp msgid "Allowed: a-z, A-Z, 0-9 and _" msgstr "Permitido: a-z, A-Z, 0-9 y _" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Built-in script (into scene file)" msgstr "Script integrado (en el archivo de escena)" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Create new script file" -msgstr "Crear script" +msgstr "Crear nuevo archivo de script" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Load existing script file" -msgstr "Script siguiente" +msgstr "Cargar archivo de script existente" #: editor/script_create_dialog.cpp msgid "Language" msgstr "Idioma" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Inherits" -msgstr "Hereda:" +msgstr "Hereda" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Class Name" -msgstr "Nombre de clase:" +msgstr "Nombre de clase" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Template" -msgstr "Remover Item" +msgstr "Plantilla" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Built-in Script" msgstr "Script integrado" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Attach Node Script" -msgstr "Crear script de nodo" +msgstr "Adjuntar script de nodo" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Remote " -msgstr "Quitar" +msgstr "Remoto " #: editor/script_editor_debugger.cpp msgid "Bytes:" @@ -7361,9 +7046,8 @@ msgid "Child Process Connected" msgstr "Proceso Hijo Conectado" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Copy Error" -msgstr "Errores de carga" +msgstr "Error de copia" #: editor/script_editor_debugger.cpp msgid "Inspect Previous Instance" @@ -7459,7 +7143,7 @@ msgstr "Atajos" #: editor/settings_config_dialog.cpp msgid "Binding" -msgstr "" +msgstr "Asignación" #: editor/spatial_editor_gizmos.cpp msgid "Change Light Radius" @@ -7506,59 +7190,52 @@ msgid "Change Particles AABB" msgstr "Cambiar partÃculas AABB" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Change Probe Extents" -msgstr "Cambiar Alcances de Notificadores" +msgstr "Cambiar Alcance de la Sonda" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Select the dynamic library for this entry" -msgstr "" +msgstr "Selecciona la librerÃa dinámica para esta entrada" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Select dependencies of the library for this entry" -msgstr "" +msgstr "Selecciona las dependencias de la librerÃa para esta entrada" #: modules/gdnative/gdnative_library_editor_plugin.cpp -#, fuzzy msgid "Remove current entry" -msgstr "Quitar Punto de ruta" +msgstr "Borrar entrada actual" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Double click to create a new entry" -msgstr "" +msgstr "Doble click para crear una nueva entrada" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Platform:" -msgstr "" +msgstr "Plataforma:" #: modules/gdnative/gdnative_library_editor_plugin.cpp -#, fuzzy msgid "Platform" -msgstr "Copiar a plataforma…" +msgstr "Plataforma" #: modules/gdnative/gdnative_library_editor_plugin.cpp -#, fuzzy msgid "Dynamic Library" -msgstr "MeshLibrary.." +msgstr "LibrerÃa dinámica" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Add an architecture entry" -msgstr "" +msgstr "Añadir entrada de arquitectura" #: modules/gdnative/gdnative_library_editor_plugin.cpp -#, fuzzy msgid "GDNativeLibrary" -msgstr "GDNative" +msgstr "\"GDNativeLibrary\"" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Library" -msgstr "MeshLibrary.." +msgstr "Biblioteca" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Status" -msgstr "Estado:" +msgstr "Estado" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Libraries: " @@ -7566,7 +7243,7 @@ msgstr "Bibliotecas: " #: modules/gdnative/register_types.cpp msgid "GDNative" -msgstr "GDNative" +msgstr "\"GDNative\"" #: modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -7623,54 +7300,56 @@ msgid "Object can't provide a length." msgstr "El objeto no puede proporcionar una longitud." #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "GridMap Delete Selection" -msgstr "Quitar seleccionados" +msgid "Next Plane" +msgstr "Plano siguiente" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "Duplicar selección" +msgid "Previous Plane" +msgstr "Plano anterior" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "Plano:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "Suelo Posterior" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Suelo Anterior" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Floor:" -msgstr "Piso:" +msgstr "Suelo:" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "Grid Map" -msgstr "Adherir a cuadrÃcula" +msgid "GridMap Delete Selection" +msgstr "GridMap Quitar seleccionados" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "Snap View" -msgstr "Vista superior" +msgid "GridMap Duplicate Selection" +msgstr "GridMap Duplicar selección" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "Previous Floor" -msgstr "Pestaña anterior" +msgid "Grid Map" +msgstr "Rejilla" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "Next Floor" -msgstr "Próximo Piso" +msgid "Snap View" +msgstr "Fijar Vista" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Clip Disabled" -msgstr "Desactivado" +msgstr "Clip Deshabilitado" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Clip Above" -msgstr "Clip superior" +msgstr "Clip Arriba" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Clip Below" -msgstr "Clip inferior" +msgstr "Clip Debajo" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Edit X Axis" @@ -7685,122 +7364,108 @@ msgid "Edit Z Axis" msgstr "Editar eje Z" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cursor Rotate X" -msgstr "Ctrl: Rotar" +msgstr "Rotar cursor X" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cursor Rotate Y" -msgstr "Ctrl: Rotar" +msgstr "Rotar cursor Y" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cursor Rotate Z" -msgstr "Ctrl: Rotar" +msgstr "Rotar cursor Z" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cursor Back Rotate X" msgstr "Rotar cursor trasero X" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cursor Back Rotate Y" msgstr "Rotar cursor trasero Y" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cursor Back Rotate Z" msgstr "Rotar cursor trasero Z" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cursor Clear Rotation" msgstr "Quitar rotación del cursor" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Create Area" -msgstr "Crear nuevo" +msgstr "Crear area" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Create Exterior Connector" -msgstr "Crear proyecto nuevo" +msgstr "Crear conector exterior" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Erase Area" -msgstr "Borrar TileMap" +msgstr "Borrar area" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Clear Selection" -msgstr "Centrar selección" +msgstr "Deseleccionar" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "GridMap Settings" -msgstr "Ajustes de fijado" +msgstr "Ajustes del GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Pick Distance:" -msgstr "Instancia:" +msgstr "Seleccionar distancia:" #: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy msgid "Generating solution..." -msgstr "Creando octree de texturas" +msgstr "Generando solución..." #: modules/mono/editor/godotsharp_editor.cpp msgid "Generating C# project..." -msgstr "" +msgstr "Generando proyecto C#..." #: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy msgid "Failed to create solution." -msgstr "¡No se pudo crear el contorno!" +msgstr "Fallo al crear solución." #: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy msgid "Failed to save solution." -msgstr "Hubo un problema al cargar el recurso." +msgstr "Fallo al guardar solución." #: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy msgid "Done" -msgstr "¡Hecho!" +msgstr "Hecho" #: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy msgid "Failed to create C# project." -msgstr "Hubo un problema al cargar el recurso." +msgstr "Fallo al crear proyecto C#." #: modules/mono/editor/godotsharp_editor.cpp msgid "Mono" msgstr "Mono" #: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy +msgid "About C# support" +msgstr "Sobre el soporte de C#" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" -msgstr "Crear contorno" +msgstr "Crear solución C#" #: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy msgid "Builds" msgstr "Compilaciones" #: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy msgid "Build Project" -msgstr "Proyecto" +msgstr "Compilar proyecto" #: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy msgid "Warnings" -msgstr "Advertencia" +msgstr "Advertencias" + +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" #: modules/visual_script/visual_script.cpp msgid "" @@ -7841,29 +7506,24 @@ msgid "Stack overflow with stack depth: " msgstr "Desbordamiento de pila en el nivel: " #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Change Signal Arguments" -msgstr "Editar argumentos de señal:" +msgstr "Cambiar argumentos de la señal" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Change Argument Type" -msgstr "Cambiar tipo de valor del «array»" +msgstr "Cambiar tipo del argumento" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Change Argument name" -msgstr "Cambiar Nombre de Entrada" +msgstr "Cambiar nombre del argumento" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Set Variable Default Value" -msgstr "Cambiar Valor por Defecto" +msgstr "Establecer valor por defecto de la variable" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Set Variable Type" -msgstr "Editar variable:" +msgstr "Establecer tipo de la variable" #: modules/visual_script/visual_script_editor.cpp msgid "Functions:" @@ -7906,54 +7566,48 @@ msgid "Add Signal" msgstr "Añadir señal" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Change Expression" -msgstr "Cambiar tipo" +msgstr "Cambiar expresión" #: modules/visual_script/visual_script_editor.cpp msgid "Add Node" msgstr "Añadir nodo" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Remove VisualScript Nodes" -msgstr "Quitar claves incorrectas" +msgstr "Quitar nodos de VisualScript" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Duplicate VisualScript Nodes" -msgstr "Duplicar Nodo(s) de Gráfico" +msgstr "Duplicar nodos de VisualScript" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." msgstr "" -"Mantén pulsado Meta para quitar un «Setter». Mantén pulsado Mayús para " -"quitar una firma genérica." +"Mantén pulsado %s para soltar un «Getter». Mantén pulsado Shift para soltar " +"una signatura genérica." #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature." msgstr "" -"Mantén pulsado Ctrl para quitar un «Getter». Mantén pulsado Mayús para " -"quitar una firma genérica." +"Mantén pulsado Ctrl para soltar un «Getter». Mantén pulsado Mayús para " +"soltar una signatura genérica." #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Hold %s to drop a simple reference to the node." -msgstr "Mantén pulsado Meta para quitar una referencia simple del nodo." +msgstr "Mantén pulsado %s para quitar una referencia simple del nodo." #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a simple reference to the node." -msgstr "Mantén pulsado Ctrl para quitar una referencia simple del nodo." +msgstr "Mantén pulsado Ctrl para soltar una referencia al nodo." #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Hold %s to drop a Variable Setter." -msgstr "Mantén pulsado Meta para quitar un «Setter» de variable." +msgstr "Mantén pulsado %s para quitar un «Setter» de variable." #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a Variable Setter." -msgstr "Mantén pulsado Ctrl para quitar un «Setter» de variable." +msgstr "Mantén pulsado Ctrl para soltar un «Setter» de variable." #: modules/visual_script/visual_script_editor.cpp msgid "Add Preload Node" @@ -7972,39 +7626,32 @@ msgid "Add Setter Property" msgstr "Añadir propiedad «Setter»" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Change Base Type" -msgstr "Cambiar tipo" +msgstr "Cambiar tipo base" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Move Node(s)" -msgstr "Borrar nodos" +msgstr "Mover nodo/s" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Remove VisualScript Node" -msgstr "Quitar Nodo de Gráfico de Shaders" +msgstr "Quitar nodo de VisualScript" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Connect Nodes" -msgstr "Conectar a nodo:" +msgstr "Conectar nodos" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Condition" -msgstr "Copiar animación" +msgstr "Condición" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Sequence" msgstr "Secuencia" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Switch" -msgstr "Altura" +msgstr "Interruptor" #: modules/visual_script/visual_script_editor.cpp msgid "Iterator" @@ -8012,61 +7659,55 @@ msgstr "Iterador" #: modules/visual_script/visual_script_editor.cpp msgid "While" -msgstr "Mientras" +msgstr "Mientras (\"While\")" #: modules/visual_script/visual_script_editor.cpp msgid "Return" -msgstr "Devuelve" +msgstr "Devuelve (\"Return\")" #: modules/visual_script/visual_script_editor.cpp msgid "Call" -msgstr "Llamada" +msgstr "Llamada (\"Call\")" #: modules/visual_script/visual_script_editor.cpp msgid "Get" -msgstr "Obtener" +msgstr "Obtener (\"Get\")" #: modules/visual_script/visual_script_editor.cpp msgid "Script already has function '%s'" msgstr "El script ya contiene la función '%s'" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Change Input Value" -msgstr "Cambiar Nombre de Entrada" +msgstr "Cambiar valor de entrada" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Can't copy the function node." -msgstr "No se puede operar en «…»" +msgstr "No se puede copiar el nodo de función." #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Clipboard is empty!" -msgstr "¡El portapapeles de recursos está vacÃo!" +msgstr "¡El portapapeles está vacÃo!" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Paste VisualScript Nodes" -msgstr "Pegar pose" +msgstr "Pegar nodos de VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Remove Function" msgstr "Quitar función" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Edit Variable" -msgstr "Editar variable:" +msgstr "Editar variable" #: modules/visual_script/visual_script_editor.cpp msgid "Remove Variable" msgstr "Quitar variable" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Edit Signal" -msgstr "Editando señal:" +msgstr "Editar señal" #: modules/visual_script/visual_script_editor.cpp msgid "Remove Signal" @@ -8090,11 +7731,11 @@ msgstr "Nodos disponibles:" #: modules/visual_script/visual_script_editor.cpp msgid "Select or create a function to edit graph" -msgstr "Selecciona o crea una función para editar el grafo" +msgstr "Selecciona o crea una función para editar el gráfico" #: modules/visual_script/visual_script_editor.cpp msgid "Edit Signal Arguments:" -msgstr "Editar argumentos de señal:" +msgstr "Editar argumentos de la señal:" #: modules/visual_script/visual_script_editor.cpp msgid "Edit Variable:" @@ -8105,24 +7746,20 @@ msgid "Delete Selected" msgstr "Quitar seleccionados" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Find Node Type" -msgstr "Buscar por tipo de nodo" +msgstr "Buscar tipo de nodo" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Copy Nodes" -msgstr "Copiar pose" +msgstr "Copiar nodos" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Cut Nodes" -msgstr "Crear nodo" +msgstr "Cortar nodos" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Paste Nodes" -msgstr "Pegar pose" +msgstr "Pegar nodos" #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " @@ -8138,7 +7775,7 @@ msgstr "El iterador ya no es correcto: " #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name." -msgstr "El nombre de la propiedad Ãndice no es correcto." +msgstr "Ãndice del nombre de la propiedad inválido." #: modules/visual_script/visual_script_func_nodes.cpp msgid "Base object is not a Node!" @@ -8150,7 +7787,7 @@ msgstr "¡La ruta no apunta a un nodo!" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name '%s' in node %s." -msgstr "El nombre de la propiedad Ãndice en el nodo %s no es correcto." +msgstr "Ãndice inválido de nombre de propiedad '%s' en el nodo %s." #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " @@ -8172,7 +7809,7 @@ msgstr "VariableSet no encontrado en el script: " msgid "Custom node has no _step() method, can't process graph." msgstr "" "El nodo personalizado no tiene ningún método _step(), no se puede procesar " -"el grafo." +"el gráfico." #: modules/visual_script/visual_script_nodes.cpp msgid "" @@ -8183,51 +7820,44 @@ msgstr "" "o string/cadena (error)." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Run in Browser" -msgstr "Examinar" +msgstr "Ejecutar en navegador" #: platform/javascript/export/export.cpp msgid "Run exported HTML in the system's default browser." msgstr "Ejecutar HTML exportado en el navegador por defecto del sistema." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not write file:" -msgstr "No se pudo cargar el tile:" +msgstr "No se puede escribir en el archivo:" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not open template for export:" -msgstr "No se pudo crear la carpeta." +msgstr "No se pudo abrir la plantilla para exportar:" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Invalid export template:" -msgstr "Instalar plantillas de exportación" +msgstr "Plantilla de exportación inválida:" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not read custom HTML shell:" -msgstr "No se pudo cargar el tile:" +msgstr "No se puede leer shell HTML personalizada:" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not read boot splash image file:" -msgstr "No se pudo cargar el tile:" +msgstr "No se pudo leer la imagen de carga:" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Using default boot splash image." -msgstr "No se pudo cargar el tile:" +msgstr "Usando la imagen de carga por defecto." #: scene/2d/animated_sprite.cpp msgid "" "A SpriteFrames resource must be created or set in the 'Frames' property in " "order for AnimatedSprite to display frames." msgstr "" -"Un recurso SpriteFrames debe ser creado o seteado en la propiedad 'Frames' " -"para que AnimatedSprite pueda mostrar frames." +"Se debe crear un recurso \"SpriteFrames\" o asignar uno en la propiedad " +"'Frames' para que AnimatedSprite pueda mostrar fotogramas." #: scene/2d/canvas_modulate.cpp msgid "" @@ -8235,8 +7865,8 @@ msgid "" "scenes). The first created one will work, while the rest will be ignored." msgstr "" "Solo se permite un CanvasModulate visible por escena (o set de escenas " -"instanciadas). El primero creado va a funcionar, mientras que el resto van a " -"ser ignorados." +"instanciadas). El primero en crearse es el que va a funcionar, mientras que " +"el resto van a ser ignorados." #: scene/2d/collision_object_2d.cpp msgid "" @@ -8244,6 +7874,10 @@ msgid "" "Consider adding CollisionShape2D or CollisionPolygon2D children nodes to " "define its shape." msgstr "" +"Este nodo no tiene formas hijas, por lo que no puede interactuar con el " +"espacio.\n" +"Considere añadir CollisionShape2D o CollisionPolygon2D como hijo para " +"definir su forma." #: scene/2d/collision_polygon_2d.cpp msgid "" @@ -8251,13 +7885,14 @@ msgid "" "CollisionObject2D derived node. Please only use it as a child of Area2D, " "StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." msgstr "" -"CollisionPolylgon2D solo sirve para proveer de un collision shape a un nodo " -"derivado de CollisionObject2D. Favor de usarlo solo como un hijo de Area2D, " -"StaticBody2D, RigidBody2D, KinematicBody2D, etc. para darles un shape." +"CollisionPolygon2D solo sirve para proveer de una forma de colisión a un " +"nodo derivado de CollisionObject2D. Por favor, úsalo solo como hijo de " +"Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. para dotarlos de " +"una forma." #: scene/2d/collision_polygon_2d.cpp msgid "An empty CollisionPolygon2D has no effect on collision." -msgstr "Un CollisionPolygon2D vacÃo no tiene efecto en la colisión." +msgstr "Un CollisionPolygon2D vacÃo no tiene ningún efecto en las colisiones." #: scene/2d/collision_shape_2d.cpp msgid "" @@ -8265,24 +7900,25 @@ msgid "" "CollisionObject2D derived node. Please only use it as a child of Area2D, " "StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape." msgstr "" -"CollisionShape2D solo sirve para proveer de un collision shape a un nodo " -"derivado de CollisionObject2D. Favor de usarlo solo como un hijo de Area2D, " -"StaticBody2D, RigidBody2D, KinematicBody2D, etc. para darles un shape." +"CollisionShape2D solo sirve para proveer de una forma de colisión a un nodo " +"derivado de \"CollisionObject2D\". Por favor, úsalo solo como hijo de " +"Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc... para dotarlos de " +"forma." #: scene/2d/collision_shape_2d.cpp msgid "" "A shape must be provided for CollisionShape2D to function. Please create a " "shape resource for it!" msgstr "" -"Se debe proveer un shape para que CollisionShape2D funcione. Creale un " -"recurso shape!" +"Se debe de proveer de forma a CollisionShape2D para que funcione. ¡Creale un " +"recurso \"shape\"!" #: scene/2d/light_2d.cpp msgid "" "A texture with the shape of the light must be supplied to the 'texture' " "property." msgstr "" -"Se debe proveer una textura con la forma de la luz a la propiedad 'texture'." +"Se debe asignar una textura con la forma de la luz a la propiedad 'texture'." #: scene/2d/light_occluder_2d.cpp msgid "" @@ -8293,55 +7929,57 @@ msgstr "" #: scene/2d/light_occluder_2d.cpp msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" -msgstr "El polÃgono de este oclusor esta vacÃo. Dibujá un polÃgono!" +msgstr "" +"El polÃgono oclusor para este oclusor esta vacÃo. Por favor, ¡dibuja un " +"polÃgono!" #: scene/2d/navigation_polygon.cpp msgid "" "A NavigationPolygon resource must be set or created for this node to work. " "Please set a property or draw a polygon." msgstr "" -"Se debe crear o establecer un recurso NavigationPolygon para que este nodo " -"funcione. Prueba estableciendo una propiedad o dibuja un polÃgono." +"Se debe crear o asignar un recurso NavigationPolygon a este nodo para que " +"funcione. Por favor, establece la propiedad o dibuja un polÃgono." #: scene/2d/navigation_polygon.cpp msgid "" "NavigationPolygonInstance must be a child or grandchild to a Navigation2D " "node. It only provides navigation data." msgstr "" -"NavigationPolygonInstance debe ser un hijo o nieto de un nodo Navigation2D. " +"NavigationPolygonInstance debe ser hijo o nieto de un nodo \"Navigation2D\". " "Solo provee datos de navegación." #: scene/2d/parallax_layer.cpp msgid "" "ParallaxLayer node only works when set as child of a ParallaxBackground node." msgstr "" -"ParallaxLayer node solo funciona cuando esta seteado como hijo de un nodo " -"ParallaxBackground." +"En nodo \"ParallaxLayer\" solo funciona cuando esta posicionado como hijo de " +"un nodo \"ParallaxBackground\"." #: scene/2d/particles_2d.cpp scene/3d/particles.cpp -#, fuzzy msgid "" "A material to process the particles is not assigned, so no behavior is " "imprinted." msgstr "" "No se ha asignado un material para procesar las partÃculas, por lo que no se " -"ha grabado ningún comportamiento." +"muestra ningún comportamiento." #: scene/2d/path_2d.cpp msgid "PathFollow2D only works when set as a child of a Path2D node." msgstr "" -"PathFollow2D solo funciona cuando está seteado como hijo de un nodo Path2D." +"\"PathFollow2D\" solo funciona cuando está posicionado como hijo de un nodo " +"\"Path2D\"." #: scene/2d/physics_body_2d.cpp -#, fuzzy msgid "" "Size changes to RigidBody2D (in character or rigid modes) will be overridden " "by the physics engine when running.\n" "Change the size in children collision shapes instead." msgstr "" -"Los cambios en el tamaño del RigidBody2D (en el personaje o modos rÃgidos) " -"serán sobreescritas por el engine de fÃsicas cuando se ejecute.\n" -"En vez de eso, cambia el tamaño en las formas de colisión hijas." +"Los cambios en el tamaño del RigidBody2D (en los modos \"character\" o " +"\"rigid\") serán sobre-escritos por el motor de fÃsicas cuando éste se " +"ejecute.\n" +"En lugar de esto, cambie el tamaño en las formas de colisión hijas." #: scene/2d/remote_transform_2d.cpp msgid "Path property must point to a valid Node2D node to work." @@ -8352,8 +7990,8 @@ msgid "" "VisibilityEnable2D works best when used with the edited scene root directly " "as parent." msgstr "" -"VisibilityEnable2D funciona mejor cuando se usa con la raÃz de escena " -"editada directamente como padre." +"VisibilityEnable2D funciona mejor cuando se usa directamente con la raÃz de " +"la escena editada como padre." #: scene/3d/arvr_nodes.cpp msgid "ARVRCamera must have an ARVROrigin node as its parent" @@ -8364,49 +8002,52 @@ msgid "ARVRController must have an ARVROrigin node as its parent" msgstr "ARVRController tiene que tener un nodo ARVROrigin como padre" #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The controller id must not be 0 or this controller will not be bound to an " "actual controller" msgstr "" -"El id del controlador no puede ser 0 o este controlador no se asignará a un " -"controlador de verdad." +"El id del controlador no puede ser 0 o este controlador no será asignado a " +"un controlador de verdad" #: scene/3d/arvr_nodes.cpp msgid "ARVRAnchor must have an ARVROrigin node as its parent" msgstr "ARVRAnchor tiene que tener un nodo ARVROrigin como padre" #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The anchor id must not be 0 or this anchor will not be bound to an actual " "anchor" msgstr "" -"El id del ancla no puede ser 0 o este ancla no se asignará a un ancla de " +"El id del ancla no puede ser 0 o este ancla no será asignada a un ancla de " "verdad" #: scene/3d/arvr_nodes.cpp msgid "ARVROrigin requires an ARVRCamera child node" -msgstr "ARVROrigin necesita un nodo ARVCamera hijo" +msgstr "ARVROrigin necesita un nodo ARVRCamera hijo" + +#: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "%d%%" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "(Tiempo restante: %d:%02d s)" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Plotting Meshes: " -msgstr "Copiando datos de imágenes" +msgstr "Trazando mallas: " #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Plotting Lights:" -msgstr "Copiando datos de imágenes" +msgstr "Trazando Iluminación:" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp msgid "Finishing Plot" -msgstr "" +msgstr "Desentramado final" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Lighting Meshes: " -msgstr "Copiando datos de imágenes" +msgstr "Iluminando Mallas: " #: scene/3d/collision_object.cpp msgid "" @@ -8414,6 +8055,10 @@ msgid "" "Consider adding CollisionShape or CollisionPolygon children nodes to define " "its shape." msgstr "" +"Este nodo no tiene formas hijas, por lo que no puede interactuar con el " +"espacio.\n" +"Considera añadir un \"CollisionShape\" o \"CollisionPolygon\" como hijos de " +"este nodo para dotarlo de una forma." #: scene/3d/collision_polygon.cpp msgid "" @@ -8421,9 +8066,9 @@ msgid "" "CollisionObject derived node. Please only use it as a child of Area, " "StaticBody, RigidBody, KinematicBody, etc. to give them a shape." msgstr "" -"CollisionPolygon solo sirve para proveer un collision shape a un nodo " -"derivado de un CollisionObject. Favor de usarlo solo como hijo de Area, " -"StaticBody, RigidBody, KinematicBody, etc. para darles un shape." +"CollisionPolygon solo sirve para proveer de una forma de colisión a un nodo " +"derivado de un CollisionObject. Por favor, úselo solo como hijo de Area, " +"StaticBody, RigidBody, KinematicBody, etc. para darles dicha forma." #: scene/3d/collision_polygon.cpp msgid "An empty CollisionPolygon has no effect on collision." @@ -8435,22 +8080,21 @@ msgid "" "derived node. Please only use it as a child of Area, StaticBody, RigidBody, " "KinematicBody, etc. to give them a shape." msgstr "" -"CollisionShape solo sirve para proveer un collision shape a un nodo derivado " -"de un CollisionObject. Favor de usarlo solo como hijo de Area, StaticBody, " -"RigidBody, KinematicBody, etc. para darles un shape." +"CollisionShape solo sirve para proveer de una forma a un nodo derivado de un " +"CollisionObject. Por favor, úsalo solo como hijo de \"Area\", \"StaticBody" +"\", \"RigidBody\", \"KinematicBody\", etc. para darles dicha forma." #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " "shape resource for it!" msgstr "" -"Se debe proveer un shape para que CollisionShape funcione. Creale un recurso " -"shape!" +"Se debe proveer de una forma a CollisionShape para que funcione. Por favor, " +"¡crea un recurso \"shape\"!" #: scene/3d/gi_probe.cpp -#, fuzzy msgid "Plotting Meshes" -msgstr "Copiando datos de imágenes" +msgstr "Trazando Mallas" #: scene/3d/navigation_mesh.cpp msgid "A NavigationMesh resource must be set or created for this node to work." @@ -8463,33 +8107,29 @@ msgid "" "NavigationMeshInstance must be a child or grandchild to a Navigation node. " "It only provides navigation data." msgstr "" -"NavigationMeshInstance debe ser un hijo o nieto de un nodo Navigation. Ya " -"que sólo proporciona los datos de navegación." +"NavigationMeshInstance debe ser hijo o nieto de un nodo Navigation. Ya que " +"sólo proporciona los datos de navegación." #: scene/3d/particles.cpp -#, fuzzy msgid "" "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" -"Nada es visible porque los modelos 3D no se han asignado a las pasadas de " -"dibujo." +"Nada es visible porque las mallas no se han asignado a los pases de dibujo." #: scene/3d/physics_body.cpp -#, fuzzy msgid "" "Size changes to RigidBody (in character or rigid modes) will be overridden " "by the physics engine when running.\n" "Change the size in children collision shapes instead." msgstr "" -"Los cambios en el tamaño del RigidBody (en el personaje o modos rÃgidos) " -"serán sobreescritas por el engine de fÃsicas cuando se ejecute.\n" -"En vez de eso, cambia el tamaño en las formas de colisión hijas." +"Los cambios en el tamaño del RigidBody (en los modos \"character\" o \"rigid" +"\") serán sobre-escritos por el motor de fÃsicas cuando se ejecute.\n" +"En lugar de esto, cambie el tamaño en las formas de colisión hijas." #: scene/3d/remote_transform.cpp -#, fuzzy msgid "Path property must point to a valid Spatial node to work." msgstr "" -"La propiedad Path debe apuntar a un nodo Particles2D valido para funcionar." +"La propiedad Path debe apuntar a un nodo Spatial válido para funcionar." #: scene/3d/scenario_fx.cpp msgid "" @@ -8503,22 +8143,20 @@ msgid "" "A SpriteFrames resource must be created or set in the 'Frames' property in " "order for AnimatedSprite3D to display frames." msgstr "" -"Un recurso SpriteFrames debe ser creado o asignado en la propiedad 'Frames' " -"para que AnimatedSprite3D pueda mostrar frames." +"Se debe crear un recurso \"SpriteFrames\" y asignarlo en la propiedad " +"'Frames' para que AnimatedSprite3D pueda mostrar fotogramas." #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "" "VehicleWheel serves to provide a wheel system to a VehicleBody. Please use " "it as a child of a VehicleBody." msgstr "" "VehicleWheel sirve para proporcionar un sistema de ruedas a un VehicleBody. " -"Úselo como un hijo de un VehicleBody." +"Por favor, úselo como hijo de un VehicleBody." #: scene/gui/color_picker.cpp -#, fuzzy msgid "Raw Mode" -msgstr "Modo desplazamiento lateral" +msgstr "Modo Raw" #: scene/gui/color_picker.cpp msgid "Add current color as a preset" @@ -8526,16 +8164,15 @@ msgstr "Añadir el color actual como predefinido" #: scene/gui/dialogs.cpp msgid "Alert!" -msgstr "Alerta!" +msgstr "¡Alerta!" #: scene/gui/dialogs.cpp msgid "Please Confirm..." msgstr "Confirmar decisión…" #: scene/gui/file_dialog.cpp -#, fuzzy msgid "Select this Folder" -msgstr "Modo de selección" +msgstr "Seleccionar esta carpeta" #: scene/gui/popup.cpp msgid "" @@ -8548,27 +8185,25 @@ msgstr "" "hacerlos visibles para editar, aunque se esconderán al ejecutar." #: scene/gui/scroll_container.cpp -#, fuzzy msgid "" "ScrollContainer is intended to work with a single child control.\n" "Use a container as child (VBox,HBox,etc), or a Control and set the custom " "minimum size manually." msgstr "" -"ScrollContainer debe funcionar con un único control de hijos.\n" -"Usa un container como hijo (VBox,HBox,etc), o un Control y ajusta el tamaño " -"mÃnimo personalizado manualmente." +"ScrollContainer está pensado para funcionar con un control hijo únicamente.\n" +"Usa un contenedor como hijo (VBox,HBox,etc), o un Control y ajusta el tamaño " +"mÃnimo manualmente." #: scene/gui/tree.cpp msgid "(Other)" msgstr "(Otros)" #: scene/main/scene_tree.cpp -#, fuzzy msgid "" "Default Environment as specified in Project Settings (Rendering -> " "Environment -> Default Environment) could not be loaded." msgstr "" -"El entorno por defecto especificado en los Ajustes del Proyecto (Renderizado " +"El entorno especificado por defecto en los Ajustes del Proyecto (Renderizado " "-> Ventana -> Entorno por Defecto) no se ha podido cargar." #: scene/main/viewport.cpp @@ -8578,10 +8213,10 @@ msgid "" "obtain a size. Otherwise, make it a RenderTarget and assign its internal " "texture to some node for display." msgstr "" -"Este viewport no está seteado como render target. Si tienes intención de que " -"muestre contenidos directo a la pantalla, hacelo un hijo de un Control para " -"que pueda obtener un tamaño. Alternativamente, hacelo un RenderTarget y " -"asigná su textura interna a algún otro nodo para mostrar." +"Este viewport no está configurado como \"render target\". Si tienes " +"intención de que muestre su contenido directamente en la pantalla, hazlo " +"hijo de un Control para que pueda obtener un tamaño. Alternativamente, hazlo " +"un RenderTarget y asigna su textura interna a algún otro nodo para mostrar." #: scene/resources/dynamic_font.cpp msgid "Error initializing FreeType." @@ -8599,6 +8234,26 @@ msgstr "Error al cargar la tipografÃa." msgid "Invalid font size." msgstr "Tamaño de tipografÃa incorrecto." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "El archivo \"version.txt\" que hay dentro de las plantillas tiene un " +#~ "formato inválido. \"Revisión\" no es un identificador válido." + +#~ msgid "Can't write file." +#~ msgstr "No se puede escribir el archivo." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "" +#~ "Por favor, elige un directorio que no contenga un archivo 'project.godot'." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "No se encontró project.godot en la ruta del proyecto." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "No se encontró project.godot en la ruta del proyecto." + #~ msgid "Next" #~ msgstr "Siguiente" diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index 55a1953d34..f2d6508201 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-01-24 20:49+0000\n" +"PO-Revision-Date: 2018-02-24 21:43+0000\n" "Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n" "Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/" "godot-engine/godot/es_AR/>\n" @@ -21,7 +21,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -2464,14 +2464,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Formato de version.txt invalido dentro de plantillas." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Formato de version.txt invalido dentro de plantillas. Revision no es un " -"identificador valido." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "No se encontro ningún version.txt dentro de las plantillas." @@ -2526,10 +2518,6 @@ msgid "Failed:" msgstr "Fallido:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "No se puede escribir el archivo." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Descarga Completa." @@ -3717,15 +3705,15 @@ msgid "Show Grid" msgstr "Mostrar la Grilla" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Mostrar ayudantes" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Mostrar reglas" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Mostrar guÃas" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4554,6 +4542,22 @@ msgid "Resource clipboard is empty!" msgstr "Clipboard de Recursos vacÃo!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Abrir en Editor" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Instancia:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Tipo:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Cargar Recurso" @@ -4840,10 +4844,6 @@ msgid "Toggle Comment" msgstr "Act/Desact. Comentario" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Clonar hacia Abajo" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "Expandir/Colapsar LÃnea" @@ -4856,6 +4856,10 @@ msgid "Unfold All Lines" msgstr "Expandir Totas las LÃneas" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Clonar hacia Abajo" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "Completar SÃmbolo" @@ -5699,11 +5703,6 @@ msgstr "Tab 2" msgid "Tab 3" msgstr "Tab 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Tipo:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Tipo de Datos:" @@ -5975,11 +5974,6 @@ msgid "Please choose an empty folder." msgstr "Por favor elegà una carpeta vacÃa." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" -"Por favor elegà una carpeta que no contenga un archivo 'project.godot'." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Proyecto Importado" @@ -6000,8 +5994,12 @@ msgid "Invalid project path (changed anything?)." msgstr "Ruta de proyecto inválida (cambiaste algo?)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "No se pudo obtener project.godot en la ruta de proyecto." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" +"No se pudo cargar project.godot desde la ruta de proyecto (error %d). La " +"ruta no existe o está corrupta." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -6020,10 +6018,6 @@ msgid "Rename Project" msgstr "Renombrar Proyecto" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "No se pudo obtener project.godot en la ruta de proyecto." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Nuevo Proyecto de Juego" @@ -6732,10 +6726,6 @@ msgstr "Sub-Recursos" msgid "Clear Inheritance" msgstr "Limpiar Herencia" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Abrir en Editor" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Eliminar Nodo(s)" @@ -6853,10 +6843,6 @@ msgstr "" "Click para mostrar el panel de grupos." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "Instancia:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Abrir script" @@ -7288,32 +7274,44 @@ msgid "Object can't provide a length." msgstr "El objeto no puede proveer un largo." #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "Eliminar Seleccionados en GridMap" +msgid "Next Plane" +msgstr "Plano siguiente" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "Duplicar Selección en GridMap" +msgid "Previous Plane" +msgstr "Plano anterior" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "Plano:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "Piso Siguiente" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Piso Anterior" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "Piso:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "Mapa de Grilla" +msgid "GridMap Delete Selection" +msgstr "Eliminar Seleccionados en GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "Anclar Vista" +msgid "GridMap Duplicate Selection" +msgstr "Duplicar Selección en GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "Piso Anterior" +msgid "Grid Map" +msgstr "Mapa de Grilla" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "Piso Siguiente" +msgid "Snap View" +msgstr "Anclar Vista" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7420,6 +7418,10 @@ msgid "Mono" msgstr "Mono" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "Sobre el soporte de C#" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "Crear solución en C#" @@ -7435,6 +7437,10 @@ msgstr "Construir Proyecto" msgid "Warnings" msgstr "Advertencias" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7987,6 +7993,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin requiere un nodo hijo ARVRCamera" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "%d%%" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "(Tiempo Restante: %d:%02d s)" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "Ploteando Meshes: " @@ -8185,6 +8199,26 @@ msgstr "Error cargando tipografÃa." msgid "Invalid font size." msgstr "Tamaño de tipografÃa inválido." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Formato de version.txt invalido dentro de plantillas. Revision no es un " +#~ "identificador valido." + +#~ msgid "Can't write file." +#~ msgstr "No se puede escribir el archivo." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "" +#~ "Por favor elegà una carpeta que no contenga un archivo 'project.godot'." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "No se pudo obtener project.godot en la ruta de proyecto." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "No se pudo obtener project.godot en la ruta de proyecto." + #~ msgid "Next" #~ msgstr "Siguiente" diff --git a/editor/translations/extract.py b/editor/translations/extract.py index bbc157788d..4b3f416343 100755 --- a/editor/translations/extract.py +++ b/editor/translations/extract.py @@ -52,11 +52,7 @@ msgstr "" "Content-Transfer-Encoding: 8-bit\\n" """ -print("Updating the editor.pot template...") - -for fname in matches: - - f = open(fname, "rb") +def process_file(f, fname): l = f.readline() lc = 1 @@ -100,12 +96,14 @@ for fname in matches: l = f.readline() lc += 1 - f.close() +print("Updating the editor.pot template...") +for fname in matches: + with open(fname, "rb") as f: + process_file(f, fname) -f = open("editor.pot", "wb") -f.write(main_po) -f.close() +with open("editor.pot", "wb") as f: + f.write(main_po) if (os.name == "posix"): print("Wrapping template at 79 characters for compatibility with Weblate.") diff --git a/editor/translations/fa.po b/editor/translations/fa.po index 3d6b98f49d..7bcbeb15f0 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -2399,12 +2399,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2459,10 +2453,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "ناتوان در نوشتن پرونده." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "دانلود کامل." @@ -3644,15 +3634,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4484,6 +4474,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "گشودن در ویرایشگر" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4774,10 +4780,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "برو به خط" @@ -4791,6 +4793,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5644,11 +5650,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5917,10 +5918,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "پروژه واردشده" @@ -5942,7 +5939,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5962,10 +5961,6 @@ msgid "Rename Project" msgstr "تغییر نام پروژه" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "پروژه بازی جدید" @@ -6665,10 +6660,6 @@ msgstr "زیرمنبع‌ها:" msgid "Clear Inheritance" msgstr "پاک کردن ارث‌بری" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "گشودن در ویرایشگر" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Øذ٠گره(ها)" @@ -6779,10 +6770,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "باز کردن Ùˆ اجرای یک اسکریپت" @@ -7231,33 +7218,47 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "انتخاب شده را ØØ°Ù Ú©Ù†" +msgid "Next Plane" +msgstr "زبانه بعدی" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "انتخاب شده را به دو تا تکثیر Ú©Ù†" +msgid "Previous Plane" +msgstr "زبانه قبلی" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +#, fuzzy +msgid "Previous Floor" +msgstr "زبانه قبلی" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Previous Floor" -msgstr "زبانه قبلی" +msgid "GridMap Delete Selection" +msgstr "انتخاب شده را ØØ°Ù Ú©Ù†" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Duplicate Selection" +msgstr "انتخاب شده را به دو تا تکثیر Ú©Ù†" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7370,6 +7371,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "انتخاب شده را تغییر مقیاس بده" @@ -7387,6 +7392,10 @@ msgstr "پروژه" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7942,6 +7951,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8128,6 +8145,9 @@ msgstr "خطای بارگذاری قلم." msgid "Invalid font size." msgstr "اندازهٔ قلم نامعتبر." +#~ msgid "Can't write file." +#~ msgstr "ناتوان در نوشتن پرونده." + #~ msgid "Next" #~ msgstr "بعدی" diff --git a/editor/translations/fi.po b/editor/translations/fi.po index 8e8636973e..efc69a02bb 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -7,12 +7,13 @@ # Bastian Salmela <bastian.salmela@gmail.com>, 2017. # ekeimaja <ekeimaja@gmail.com>, 2017-2018. # Jarmo Riikonen <amatrelan@gmail.com>, 2017. +# Sami Lehtilä <sami.lehtila@gmail.com>, 2018. # msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-01-24 12:10+0000\n" -"Last-Translator: ekeimaja <ekeimaja@gmail.com>\n" +"PO-Revision-Date: 2018-01-31 04:36+0000\n" +"Last-Translator: Sami Lehtilä <sami.lehtila@gmail.com>\n" "Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/" "godot/fi/>\n" "Language: fi\n" @@ -159,9 +160,8 @@ msgid "Linear" msgstr "Lineaarinen" #: editor/animation_editor.cpp editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Constant" -msgstr "Jatkuva" +msgstr "Muuttumaton" #: editor/animation_editor.cpp msgid "In" @@ -192,9 +192,8 @@ msgid "Clean-Up Animation" msgstr "Siivoa animaatio" #: editor/animation_editor.cpp -#, fuzzy msgid "Create NEW track for %s and insert key?" -msgstr "Luo uusi raita %s ja lisää avain?" +msgstr "Luo UUSI raita %lle ja lisää avain?" #: editor/animation_editor.cpp msgid "Create %d NEW tracks and insert keys?" @@ -225,14 +224,12 @@ msgid "Change Anim Len" msgstr "Vaihda animaation pituutta" #: editor/animation_editor.cpp -#, fuzzy msgid "Change Anim Loop" -msgstr "Vaihda animaation toistoa" +msgstr "Vaihda animaation kierto" #: editor/animation_editor.cpp -#, fuzzy msgid "Anim Create Typed Value Key" -msgstr "Animaatio: Luo tyyppipohjainen arvo avain" +msgstr "Animaatio: Luo tyypitetty arvoavain" #: editor/animation_editor.cpp msgid "Anim Insert" @@ -243,9 +240,8 @@ msgid "Anim Scale Keys" msgstr "Animaatio: Skaalaa avaimia" #: editor/animation_editor.cpp -#, fuzzy msgid "Anim Add Call Track" -msgstr "Animaatio: Lisää kutsu raita" +msgstr "Animaatio: Lisää kutsuraita" #: editor/animation_editor.cpp msgid "Animation zoom." @@ -264,9 +260,8 @@ msgid "Step (s):" msgstr "Askellus:" #: editor/animation_editor.cpp -#, fuzzy msgid "Cursor step snap (in seconds)." -msgstr "Kohdistimen tarttuminen (sekunneissa)." +msgstr "Kohdistimen askelrajoitin (sekunneissa)." #: editor/animation_editor.cpp msgid "Enable/Disable looping in animation." @@ -302,15 +297,15 @@ msgstr "Animaation optimoija" #: editor/animation_editor.cpp msgid "Max. Linear Error:" -msgstr "" +msgstr "Max. lineaarinen virhe:" #: editor/animation_editor.cpp msgid "Max. Angular Error:" -msgstr "" +msgstr "Max. Kulmavirhe:" #: editor/animation_editor.cpp msgid "Max Optimizable Angle:" -msgstr "" +msgstr "Max. Optimoitava kulma:" #: editor/animation_editor.cpp msgid "Optimize" @@ -504,9 +499,8 @@ msgid "Connecting Signal:" msgstr "Yhdistävä signaali:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Disconnect '%s' from '%s'" -msgstr "Yhdistä '%s' '%s':n" +msgstr "Katkaise yhteys '%s' '%s':n" #: editor/connections_dialog.cpp msgid "Connect.." @@ -522,9 +516,8 @@ msgid "Signals" msgstr "Signaalit" #: editor/create_dialog.cpp -#, fuzzy msgid "Change %s Type" -msgstr "Muuta tyyppiä" +msgstr "Muuta %s:n tyyppi" #: editor/create_dialog.cpp editor/project_settings_editor.cpp #: modules/visual_script/visual_script_editor.cpp @@ -532,9 +525,8 @@ msgid "Change" msgstr "Muuta" #: editor/create_dialog.cpp -#, fuzzy msgid "Create New %s" -msgstr "Luo uusi" +msgstr "Luo uusi %s" #: editor/create_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp @@ -648,7 +640,7 @@ msgstr "" #: editor/dependency_editor.cpp #, fuzzy msgid "Cannot remove:" -msgstr "Ei voida poistaa:\n" +msgstr "Ei voida poistaa:" #: editor/dependency_editor.cpp msgid "Error loading:" @@ -2513,14 +2505,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Paketti sisältää viallisen version.txt tiedoston." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Paketti sisältää viallisen version.txt tiedoston. 'Revision' ei ole " -"hyväksytty tunniste." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "version.txt -tiedostoa ei löytynyt." @@ -2578,11 +2562,6 @@ msgstr "Epäonnistui:" #: editor/export_template_manager.cpp #, fuzzy -msgid "Can't write file." -msgstr "Ei voitu kirjoittaa tiedostoa:\n" - -#: editor/export_template_manager.cpp -#, fuzzy msgid "Download Complete." msgstr "Lataa" @@ -3820,15 +3799,15 @@ msgstr "Näytä ruudukko" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy -msgid "Show helpers" +msgid "Show Helpers" msgstr "Näytä luut" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Näytä viivaimet" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Näytä apuviivat" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4678,6 +4657,22 @@ msgid "Resource clipboard is empty!" msgstr "Resurssien leikepöytä on tyhjä!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Avaa editorissa" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Tyyppi:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Lataa resurssi" @@ -4975,10 +4970,6 @@ msgid "Toggle Comment" msgstr "Näytä/Piilota kommentit" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Kloonaa alas" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "Avaa rivi" @@ -4992,6 +4983,10 @@ msgid "Unfold All Lines" msgstr "Avaa kaikki rivit" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Kloonaa alas" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "Täydennä symbooli" @@ -5868,11 +5863,6 @@ msgstr "Välilehti 2" msgid "Tab 3" msgstr "Välilehti 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Tyyppi:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Tietotyyppi:" @@ -6144,10 +6134,6 @@ msgid "Please choose an empty folder." msgstr "Ole hyvä ja valitse 'project.godot' tiedosto." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "Ole hyvä ja valitse hakemisto jossa ei ole 'project.godot' tiedostoa." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Tuotu projekti" @@ -6170,7 +6156,9 @@ msgstr "Virheellinen projektin polku (muuttuiko mikään?)." #: editor/project_manager.cpp #, fuzzy -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "Ei voitu luoda godot.cfg -tiedostoa projektin polkuun." #: editor/project_manager.cpp @@ -6192,11 +6180,6 @@ msgid "Rename Project" msgstr "Nimetä projekti" #: editor/project_manager.cpp -#, fuzzy -msgid "Couldn't get project.godot in the project path." -msgstr "Ei voitu luoda godot.cfg -tiedostoa projektin polkuun." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Uusi peliprojekti" @@ -6911,10 +6894,6 @@ msgstr "Resurssit" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Avaa editorissa" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Poista Node(t)" @@ -7027,10 +7006,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "Seuraava skripti" @@ -7472,13 +7447,26 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "Poista valitut" +msgid "Next Plane" +msgstr "Seuraava välilehti" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "Monista valinta" +msgid "Previous Plane" +msgstr "Edellinen välilehti" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "Previous Floor" +msgstr "Edellinen välilehti" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" @@ -7486,22 +7474,23 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Grid Map" -msgstr "Ruudukko" +msgid "GridMap Delete Selection" +msgstr "Poista valitut" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Snap View" -msgstr "Huippunäkymä" +msgid "GridMap Duplicate Selection" +msgstr "Monista valinta" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Previous Floor" -msgstr "Edellinen välilehti" +msgid "Grid Map" +msgstr "Ruudukko" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "" +#, fuzzy +msgid "Snap View" +msgstr "Huippunäkymä" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy @@ -7621,6 +7610,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "Luo ääriviivat" @@ -7639,6 +7632,10 @@ msgstr "Uusi projekti" msgid "Warnings" msgstr "Varoitus" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -8158,6 +8155,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8334,6 +8339,29 @@ msgstr "Virhe fontin latauksessa." msgid "Invalid font size." msgstr "Virheellinen fonttikoko." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Paketti sisältää viallisen version.txt tiedoston. 'Revision' ei ole " +#~ "hyväksytty tunniste." + +#, fuzzy +#~ msgid "Can't write file." +#~ msgstr "Ei voitu kirjoittaa tiedostoa:\n" + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "" +#~ "Ole hyvä ja valitse hakemisto jossa ei ole 'project.godot' tiedostoa." + +#, fuzzy +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "Ei voitu luoda godot.cfg -tiedostoa projektin polkuun." + +#, fuzzy +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "Ei voitu luoda godot.cfg -tiedostoa projektin polkuun." + #~ msgid "Next" #~ msgstr "Seuraava" diff --git a/editor/translations/fr.po b/editor/translations/fr.po index 7bb65f8056..d9fd96081f 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -8,10 +8,11 @@ # Arthur Templé <tuturtemple@gmail.com>, 2018. # Brice <bbric@free.fr>, 2016. # Chenebel Dorian <LoubiTek54@gmail.com>, 2016-2017. +# Cindy Dallaire <c.dallaire93@gmail.com>, 2018. # derderder77 <derderder77380@gmail.com>, 2016. # finkiki <specialpopol@gmx.fr>, 2016. # Gilles Roudiere <gilles.roudiere@gmail.com>, 2017-2018. -# Hugo Locurcio <hugo.l@openmailbox.org>, 2016-2017. +# Hugo Locurcio <hugo.l@openmailbox.org>, 2016-2018. # Kanabenki <lucien.menassol@gmail.com>, 2017. # keltwookie <keltwookie@protonmail.com>, 2017. # Luc Stepniewski <lior@gradstein.info>, 2017. @@ -35,8 +36,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-01-22 08:08+0000\n" -"Last-Translator: Gilles Roudiere <gilles.roudiere@gmail.com>\n" +"PO-Revision-Date: 2018-02-24 02:36+0000\n" +"Last-Translator: Cindy Dallaire <c.dallaire93@gmail.com>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot/fr/>\n" "Language: fr\n" @@ -44,7 +45,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -1363,14 +1364,14 @@ msgid "Online Tutorials:" msgstr "Tutoriels en ligne :" #: editor/editor_help.cpp -#, fuzzy msgid "" "There are currently no tutorials for this class, you can [color=$color][url=" "$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/" "url][/color]." msgstr "" -"Pas de description disponible pour cette méthode. [color=$color][url=" -"$url]Contribuez[/url][/color] pour nous aider!" +"Pas de tutoriels disponibles pour cette classe, vous pouvez [color=$color]" +"[url=$url]en contribuer un[/url][/color] ou [color=$color][url=$url2]en " +"demander un[/url][/color]." #: editor/editor_help.cpp msgid "Properties" @@ -1424,7 +1425,6 @@ msgid "Clear" msgstr "Effacer" #: editor/editor_log.cpp -#, fuzzy msgid "Clear Output" msgstr "Effacer la sortie" @@ -2497,14 +2497,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Format de version.txt invalide dans les modèles." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Format de version.txt invalide dans les modèles. Revision n'est pas un " -"identifiant valide." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Aucun version.txt n'a été trouvé dans les modèles." @@ -2560,10 +2552,6 @@ msgid "Failed:" msgstr "Échec:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Impossible d'écrire le fichier." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Téléchargement terminé." @@ -2585,7 +2573,7 @@ msgstr "Résolution" #: editor/export_template_manager.cpp msgid "Can't Resolve" -msgstr "Impossible à résoudre." +msgstr "Impossible à résoudre" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -2762,9 +2750,8 @@ msgid "View Owners.." msgstr "Voir les propriétaires…" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Duplicate.." -msgstr "Dupliquer" +msgstr "Dupliquer…" #: editor/filesystem_dock.cpp msgid "Previous Directory" @@ -3129,7 +3116,6 @@ msgid "Directions" msgstr "Directions" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Past" msgstr "Passé" @@ -3754,15 +3740,15 @@ msgid "Show Grid" msgstr "Afficher la grille" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Afficher les aides" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Afficher les règles" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Montrer les guides" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -3826,7 +3812,6 @@ msgid "Ok" msgstr "OK" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Cannot instantiate multiple nodes without root." msgstr "Impossible d'instancier plusieurs nÅ“uds sans nÅ“ud racine." @@ -4088,12 +4073,10 @@ msgid "Create Outline Mesh.." msgstr "Créer un maillage de contour…" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "View UV1" msgstr "Afficher l'UV1" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "View UV2" msgstr "Afficher l'UV2" @@ -4235,9 +4218,8 @@ msgid "Calculating grid size..." msgstr "Calcul de la taille de la grille..." #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Creating heightfield..." -msgstr "Création de la heightmap..." +msgstr "Création de la heightmap…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Marking walkable triangles..." @@ -4264,9 +4246,8 @@ msgid "Creating polymesh..." msgstr "Création d'un maillage de contour…" #: editor/plugins/navigation_mesh_generator.cpp -#, fuzzy msgid "Converting to native navigation mesh..." -msgstr "Conversion en maillage de navigation natif..." +msgstr "Conversion en maillage de navigation natif…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Navigation Mesh Generator Setup:" @@ -4600,6 +4581,22 @@ msgid "Resource clipboard is empty!" msgstr "Le presse-papiers des ressources est vide !" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Ouvrir dans l'éditeur" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Instance :" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Type :" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Charger une ressource" @@ -4612,9 +4609,8 @@ msgid "Paste" msgstr "Coller" #: editor/plugins/resource_preloader_editor_plugin.cpp -#, fuzzy msgid "ResourcePreloader" -msgstr "Chemin de la ressource" +msgstr "ResourcePreloader" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Files" @@ -4887,10 +4883,6 @@ msgid "Toggle Comment" msgstr "Commenter/décommenter" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Cloner en dessous" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "Réduire/Développer la ligne" @@ -4903,6 +4895,10 @@ msgid "Unfold All Lines" msgstr "Dérouler toutes les lignes" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Cloner en dessous" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "Compléter le symbole" @@ -5581,27 +5577,24 @@ msgid "Insert Empty (After)" msgstr "Insérer vide (après)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Move (Before)" -msgstr "Déplacer le(s) nÅ“ud(s)" +msgstr "Déplacer avant" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Move (After)" msgstr "Déplacer (Après)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "SpriteFrames" -msgstr "Images du sprite" +msgstr "SpriteFrames" #: editor/plugins/style_box_editor_plugin.cpp msgid "StyleBox Preview:" msgstr "Aperçu de la StyleBox :" #: editor/plugins/style_box_editor_plugin.cpp -#, fuzzy msgid "StyleBox" -msgstr "Style Box" +msgstr "StyleBox" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Set Region Rect" @@ -5751,11 +5744,6 @@ msgstr "Onglet 2" msgid "Tab 3" msgstr "Onglet 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Type :" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Type de données :" @@ -5825,9 +5813,8 @@ msgid "Mirror Y" msgstr "Miroir Y" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Paint Tile" -msgstr "Peindre sur la TileMap" +msgstr "Peindre la case" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" @@ -5866,9 +5853,8 @@ msgid "Merge from scene?" msgstr "Fusionner depuis la scène ?" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tile Set" -msgstr "TileSet…" +msgstr "Ensemble de cases" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from Scene" @@ -5883,7 +5869,6 @@ msgid "Error" msgstr "Erreur" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Autotiles" msgstr "Coupe automatique" @@ -6024,11 +6009,6 @@ msgid "Please choose an empty folder." msgstr "Veuillez choisir un fichier 'project.godot'." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" -"Veuillez choisir un dossier qui ne contient pas de fichier 'project.godot'." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Projet importé" @@ -6039,7 +6019,7 @@ msgstr "Impossible de créer le dossier." #: editor/project_manager.cpp msgid "There is already a folder in this path with the specified name." -msgstr "" +msgstr "Un dossier avec le nom spécifié existe déjà dans ce chemin." #: editor/project_manager.cpp msgid "It would be a good idea to name your project." @@ -6050,9 +6030,12 @@ msgid "Invalid project path (changed anything?)." msgstr "Chemin de projet non valide (avez-vous changé quelque chose ?)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +#, fuzzy +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" -"Impossible de trouver le fichier project.godot dans le chemin du projet." +"Impossible de modifier le fichier project.godot dans le chemin du projet." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -6072,11 +6055,6 @@ msgid "Rename Project" msgstr "Renommer le projet" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" -"Impossible de trouver le fichier project.godot dans le chemin du projet." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Nouveau projet de jeu" @@ -6790,10 +6768,6 @@ msgstr "Ressources secondaires :" msgid "Clear Inheritance" msgstr "Effacer l'héritage" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Ouvrir dans l'éditeur" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Supprimer nÅ“ud(s)" @@ -6912,10 +6886,6 @@ msgstr "" "Cliquez pour montrer l'arrimage de goupes." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "Instance :" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Ouvrir script" @@ -7356,33 +7326,47 @@ msgid "Object can't provide a length." msgstr "L'objet ne peut fournir une longueur." #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "Sélection de la supression de GridMap" +#, fuzzy +msgid "Next Plane" +msgstr "Onglet suivant" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "Sélection de la duplication de GridMap" +#, fuzzy +msgid "Previous Plane" +msgstr "Onglet precedent" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "Onglet :" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "Étage suivant" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "Previous Floor" +msgstr "Onglet précédent" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "Étage :" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "Grille" +msgid "GridMap Delete Selection" +msgstr "Sélection de la supression de GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "Vue instantanée" +msgid "GridMap Duplicate Selection" +msgstr "Sélection de la duplication de GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "Previous Floor" -msgstr "Onglet précédent" +msgid "Grid Map" +msgstr "Grille" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "Étage suivant" +msgid "Snap View" +msgstr "Vue instantanée" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7467,7 +7451,7 @@ msgstr "Création des coutours..." #: modules/mono/editor/godotsharp_editor.cpp msgid "Generating C# project..." -msgstr "" +msgstr "Création du projet C# ..." #: modules/mono/editor/godotsharp_editor.cpp #, fuzzy @@ -7494,6 +7478,10 @@ msgid "Mono" msgstr "Mono" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "À propos du support C#" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "Créer le contour" @@ -7512,6 +7500,10 @@ msgstr "Projet" msgid "Warnings" msgstr "Avertissement" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -8073,6 +8065,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin requiert un nÅ“ud enfant ARVRCamera" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp #, fuzzy msgid "Plotting Meshes: " msgstr "Tracer les maillages" @@ -8273,6 +8273,29 @@ msgstr "Erreur lors du chargement de la police." msgid "Invalid font size." msgstr "Taille de police invalide." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Format de version.txt invalide dans les modèles. Revision n'est pas un " +#~ "identifiant valide." + +#~ msgid "Can't write file." +#~ msgstr "Impossible d'écrire le fichier." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "" +#~ "Veuillez choisir un dossier qui ne contient pas de fichier 'project." +#~ "godot'." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "" +#~ "Impossible de trouver le fichier project.godot dans le chemin du projet." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "" +#~ "Impossible de trouver le fichier project.godot dans le chemin du projet." + #~ msgid "Next" #~ msgstr "Suivant" diff --git a/editor/translations/he.po b/editor/translations/he.po index 57ec12e002..a5f727b8ee 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -10,15 +10,16 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-01-25 22:27+0000\n" +"PO-Revision-Date: 2018-02-22 12:37+0000\n" "Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n" "Language-Team: Hebrew <https://hosted.weblate.org/projects/godot-engine/" "godot/he/>\n" "Language: he\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2.19-dev\n" +"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " +"n % 10 == 0) ? 2 : 3));\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -70,7 +71,7 @@ msgstr "" #: editor/animation_editor.cpp msgid "Set Transitions to:" -msgstr "" +msgstr "הגדרת ×ž×¢×‘×¨×•× ×™× ×ל:" #: editor/animation_editor.cpp msgid "Anim Track Rename" @@ -143,11 +144,11 @@ msgstr "" #: editor/animation_editor.cpp msgid "Goto Next Step" -msgstr "" +msgstr "מעבר לצעד הב×" #: editor/animation_editor.cpp msgid "Goto Prev Step" -msgstr "" +msgstr "מעבר לצעד הקוד×" #: editor/animation_editor.cpp editor/plugins/curve_editor_plugin.cpp #: editor/property_editor.cpp @@ -192,7 +193,7 @@ msgstr "" #: editor/animation_editor.cpp msgid "Create %d NEW tracks and insert keys?" -msgstr "" +msgstr "ליצור %d רצועות חדשות ×•×œ×”×›× ×™×¡ מפתחות?" #: editor/animation_editor.cpp editor/create_dialog.cpp #: editor/editor_audio_buses.cpp editor/plugins/abstract_polygon_2d_editor.cpp @@ -240,7 +241,7 @@ msgstr "" #: editor/animation_editor.cpp msgid "Animation zoom." -msgstr "" +msgstr "תקריב ×”× ×¤×©×”." #: editor/animation_editor.cpp msgid "Length (s):" @@ -2373,74 +2374,64 @@ msgid "Invalid version.txt format inside templates." msgstr "×ª×‘× ×™×ª ×”Ö¾version.txt שגויה בתוך ×”×ª×‘× ×™×•×ª." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." -msgstr "" +msgstr "×œ× × ×ž×¦× version.txt בתוך ×”×ª×‘× ×™×•×ª." #: editor/export_template_manager.cpp msgid "Error creating path for templates:" -msgstr "" +msgstr "שגי×ת ביצירת × ×ª×™×‘ ×œ×ª×‘× ×™×•×ª:" #: editor/export_template_manager.cpp msgid "Extracting Export Templates" -msgstr "" +msgstr "×ª×‘× ×™×•×ª ×”×™×™×¦×•× ×ž×—×•×œ×¦×•×ª" #: editor/export_template_manager.cpp msgid "Importing:" -msgstr "" +msgstr "ייבו×:" #: editor/export_template_manager.cpp msgid "" "No download links found for this version. Direct download is only available " "for official releases." -msgstr "" +msgstr "×œ× × ×ž×¦×ו קישורי הורדה לגרסה זו. הורדה ישירה ×–×ž×™× ×” רק במהדורות הרשמיות." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve." -msgstr "" +msgstr "×œ× × ×™×ª×Ÿ לפתור." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't connect." -msgstr "" +msgstr "×œ× × ×™×ª×Ÿ להתחבר." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "No response." -msgstr "" +msgstr "×ין תגובה." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request Failed." -msgstr "" +msgstr "הבקשה × ×›×©×œ×”." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Redirect Loop." -msgstr "" +msgstr "לול×ת ×”×¤× ×™×•×ª." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed:" -msgstr "" - -#: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" +msgstr "× ×›×©×œ:" #: editor/export_template_manager.cpp msgid "Download Complete." -msgstr "" +msgstr "ההורדה הושלמה." #: editor/export_template_manager.cpp msgid "Error requesting url: " -msgstr "" +msgstr "שגי××” בבקשת כתובת: " #: editor/export_template_manager.cpp msgid "Connecting to Mirror.." @@ -2448,205 +2439,206 @@ msgstr "" #: editor/export_template_manager.cpp msgid "Disconnected" -msgstr "" +msgstr "×ž× ×•×ª×§" #: editor/export_template_manager.cpp msgid "Resolving" -msgstr "" +msgstr "פותר" #: editor/export_template_manager.cpp msgid "Can't Resolve" -msgstr "" +msgstr "×œ× × ×™×ª×Ÿ לפתור" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connecting.." -msgstr "" +msgstr "מתבצעת התחברות…" #: editor/export_template_manager.cpp msgid "Can't Connect" -msgstr "" +msgstr "×œ× × ×™×ª×Ÿ להתחבר" #: editor/export_template_manager.cpp msgid "Connected" -msgstr "" +msgstr "מחובר" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Requesting.." -msgstr "" +msgstr "מוגשת בקשה…" #: editor/export_template_manager.cpp msgid "Downloading" -msgstr "" +msgstr "מתבצעת הורדה" #: editor/export_template_manager.cpp msgid "Connection Error" -msgstr "" +msgstr "שגי×ת חיבור" #: editor/export_template_manager.cpp msgid "SSL Handshake Error" -msgstr "" +msgstr "שגי×ת לחיצת יד SSL" #: editor/export_template_manager.cpp msgid "Current Version:" -msgstr "" +msgstr "גרסה × ×•×›×—×™×ª:" #: editor/export_template_manager.cpp msgid "Installed Versions:" -msgstr "" +msgstr "גרס×ות ×ž×•×ª×§× ×•×ª:" #: editor/export_template_manager.cpp msgid "Install From File" -msgstr "" +msgstr "×”×ª×§× ×” מקובץ" #: editor/export_template_manager.cpp msgid "Remove Template" -msgstr "" +msgstr "הסרת ×ª×‘× ×™×ª" #: editor/export_template_manager.cpp msgid "Select template file" -msgstr "" +msgstr "בחירת קובץ ×ª×‘× ×™×ª" #: editor/export_template_manager.cpp msgid "Export Template Manager" -msgstr "" +msgstr "×ž× ×”×œ ×™×™×¦×•× ×ª×‘× ×™×•×ª" #: editor/export_template_manager.cpp msgid "Download Templates" -msgstr "" +msgstr "הורדת ×ª×‘× ×™×•×ª" #: editor/export_template_manager.cpp msgid "Select mirror from list: " -msgstr "" +msgstr "בחירת ×תר מר××” מהרשימה: " #: editor/file_type_cache.cpp msgid "Can't open file_type_cache.cch for writing, not saving file type cache!" msgstr "" +"×œ× × ×™×ª×Ÿ לפתוח ×ת file_type_cache.cch לכתיבה, מטמון סוג ×”×§×‘×¦×™× ×œ× ×™×™×©×ž×¨!" #: editor/filesystem_dock.cpp msgid "Cannot navigate to '%s' as it has not been found in the file system!" -msgstr "" +msgstr "×œ× × ×™×ª×Ÿ ×œ× ×•×•×˜ ×ל ‚%s’ כיוון ×©×œ× × ×ž×¦× ×‘×ž×¢×¨×›×ª הקבצי×!" #: editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails" -msgstr "" +msgstr "צפייה ×‘×¤×¨×™×˜×™× ×›×¨×©×ª של ×ª×ž×•× ×•×ª ממוזערות" #: editor/filesystem_dock.cpp msgid "View items as a list" -msgstr "" +msgstr "הצגת ×¤×¨×™×˜×™× ×›×¨×©×™×ž×”" #: editor/filesystem_dock.cpp msgid "Status: Import of file failed. Please fix file and reimport manually." -msgstr "" +msgstr "מצב: ×™×™×‘×•× ×”×§×•×‘×¥ × ×›×©×œ. × × ×œ×ª×§×Ÿ ×ת הקובץ ×•×œ×™×™×‘× ×ž×—×“×© ×™×“× ×™×ª." #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." -msgstr "" +msgstr "×œ× × ×™×ª×Ÿ להעביר/×œ×©× ×•×ª ×©× ×œ×ž×§×•×¨ של מש×בי×." #: editor/filesystem_dock.cpp msgid "Cannot move a folder into itself." -msgstr "" +msgstr "×œ× × ×™×ª×Ÿ להעביר תיקייה לתוך עצמה." #: editor/filesystem_dock.cpp msgid "Error moving:" -msgstr "" +msgstr "שגי××” בהעברה:" #: editor/filesystem_dock.cpp msgid "Error duplicating:" -msgstr "" +msgstr "שגי××” בשכפול:" #: editor/filesystem_dock.cpp msgid "Unable to update dependencies:" -msgstr "" +msgstr "×œ× × ×™×ª×Ÿ לעדכן ×ת התלויות:" #: editor/filesystem_dock.cpp msgid "No name provided" -msgstr "" +msgstr "×œ× ×¦×•×™×Ÿ ש×" #: editor/filesystem_dock.cpp msgid "Provided name contains invalid characters" -msgstr "" +msgstr "×”×©× ×©×¡×•×¤×§ מכיל ×ª×•×•×™× ×©×’×•×™×™×" #: editor/filesystem_dock.cpp msgid "No name provided." -msgstr "" +msgstr "×œ× ×¦×•×™×Ÿ ש×." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." -msgstr "" +msgstr "×”×©× ×ž×›×™×œ ×ª×•×•×™× ×©×’×•×™×™×." #: editor/filesystem_dock.cpp msgid "A file or folder with this name already exists." -msgstr "" +msgstr "כבר ×§×™×™×ž×™× ×§×•×‘×¥ ×ו תיקייה ×‘×©× ×”×–×”." #: editor/filesystem_dock.cpp msgid "Renaming file:" -msgstr "" +msgstr "×©×™× ×•×™ ×©× ×”×§×•×‘×¥:" #: editor/filesystem_dock.cpp msgid "Renaming folder:" -msgstr "" +msgstr "×©×™× ×•×™ ×©× ×”×ª×™×§×™×™×”:" #: editor/filesystem_dock.cpp msgid "Duplicating file:" -msgstr "" +msgstr "קובץ משוכפל:" #: editor/filesystem_dock.cpp msgid "Duplicating folder:" -msgstr "" +msgstr "תיקייה משוכפלת:" #: editor/filesystem_dock.cpp msgid "Expand all" -msgstr "" +msgstr "להרחיב הכול" #: editor/filesystem_dock.cpp msgid "Collapse all" -msgstr "" +msgstr "×œ×¦×ž×¦× ×”×›×•×œ" #: editor/filesystem_dock.cpp msgid "Rename.." -msgstr "" +msgstr "×©×™× ×•×™ ש×…" #: editor/filesystem_dock.cpp msgid "Move To.." -msgstr "" +msgstr "העברה ×ל…" #: editor/filesystem_dock.cpp msgid "Open Scene(s)" -msgstr "" +msgstr "פתיחת ×¡×¦× ×•×ª" #: editor/filesystem_dock.cpp msgid "Instance" -msgstr "" +msgstr "עותק" #: editor/filesystem_dock.cpp msgid "Edit Dependencies.." -msgstr "" +msgstr "עריכת תלויות…" #: editor/filesystem_dock.cpp msgid "View Owners.." -msgstr "" +msgstr "צפייה בבעלי×…" #: editor/filesystem_dock.cpp msgid "Duplicate.." -msgstr "" +msgstr "שכפול…" #: editor/filesystem_dock.cpp msgid "Previous Directory" -msgstr "" +msgstr "התיקייה הקודמת" #: editor/filesystem_dock.cpp msgid "Next Directory" -msgstr "" +msgstr "התיקייה הב××”" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" -msgstr "" +msgstr "סריקת מערכת ×”×§×‘×¦×™× ×ž×—×“×©" #: editor/filesystem_dock.cpp msgid "Toggle folder status as Favorite" -msgstr "" +msgstr "החלפת מצב התיקייה כמועדפת" #: editor/filesystem_dock.cpp msgid "Instance the selected scene(s) as child of the selected node." @@ -2657,76 +2649,78 @@ msgid "" "Scanning Files,\n" "Please Wait.." msgstr "" +"×”×§×‘×¦×™× × ×¡×¨×§×™×,\n" +"× × ×œ×”×ž×ª×™×Ÿâ€¦" #: editor/filesystem_dock.cpp msgid "Move" -msgstr "" +msgstr "העברה" #: editor/filesystem_dock.cpp editor/plugins/animation_tree_editor_plugin.cpp #: editor/project_manager.cpp msgid "Rename" -msgstr "" +msgstr "×©×™× ×•×™ ש×" #: editor/groups_editor.cpp msgid "Add to Group" -msgstr "" +msgstr "הוספה לקבוצה" #: editor/groups_editor.cpp msgid "Remove from Group" -msgstr "" +msgstr "הסרה מקבוצה" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" -msgstr "" +msgstr "×™×™×‘×•× ×›×¡×¦× ×” בודדת" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Animations" -msgstr "" +msgstr "×™×™×‘×•× ×¢× ×”× ×¤×©×•×ª × ×¤×¨×“×•×ª" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials" -msgstr "" +msgstr "×™×™×‘×•× ×¢× ×—×•×ž×¨×™× × ×¤×¨×“×™×" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects" -msgstr "" +msgstr "×™×™×‘×•× ×¢× ×¤×¨×™×˜×™× × ×¤×¨×“×™×" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials" -msgstr "" +msgstr "×™×™×‘×•× ×¢× ×¤×¨×™×˜×™+×—×•×ž×¨×™× × ×¤×¨×“×™×" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Animations" -msgstr "" +msgstr "×™×™×‘×•× ×¢× ×¤×¨×™×˜×™×+×”× ×¤×©×•×ª × ×¤×¨×“×™×" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials+Animations" -msgstr "" +msgstr "×™×™×‘×•× ×¢× ×—×•×ž×¨×™×+×”× ×¤×©×•×ª × ×¤×¨×“×™×" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials+Animations" -msgstr "" +msgstr "×™×™×‘×•× ×¢× ×¤×¨×™×˜×™×+חומרי×+×”× ×¤×©×•×ª × ×¤×¨×“×™×" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes" -msgstr "" +msgstr "×™×™×‘×•× ×›×ž×¡×¤×¨ ×¡×¦× ×•×ª" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes+Materials" -msgstr "" +msgstr "×™×™×‘×•× ×›×ž×¡×¤×¨ ×¡×¦× ×•×ª+חומרי×" #: editor/import/resource_importer_scene.cpp #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Import Scene" -msgstr "" +msgstr "×™×™×‘×•× ×¡×¦× ×”" #: editor/import/resource_importer_scene.cpp msgid "Importing Scene.." -msgstr "" +msgstr "×¡×¦× ×” מיוב×ת…" #: editor/import/resource_importer_scene.cpp msgid "Generating Lightmaps" -msgstr "" +msgstr "× ×•×¦×¨×•×ª מפות ת×ורה" #: editor/import/resource_importer_scene.cpp msgid "Generating for Mesh: " @@ -2734,11 +2728,11 @@ msgstr "" #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script.." -msgstr "" +msgstr "מופעל סקריפט מות×× ×ישית…" #: editor/import/resource_importer_scene.cpp msgid "Couldn't load post-import script:" -msgstr "" +msgstr "×œ× × ×™×ª×Ÿ לטעון סקריפט של×חר ייבו×:" #: editor/import/resource_importer_scene.cpp msgid "Invalid/broken script for post-import (check console):" @@ -2750,31 +2744,31 @@ msgstr "" #: editor/import/resource_importer_scene.cpp msgid "Saving.." -msgstr "" +msgstr "שמירה…" #: editor/import_dock.cpp msgid "Set as Default for '%s'" -msgstr "" +msgstr "הגדרה כבררת מחדל עבור ‚%s’" #: editor/import_dock.cpp msgid "Clear Default for '%s'" -msgstr "" +msgstr "מחיקת בררת מחדל עבור ‚%s’" #: editor/import_dock.cpp msgid " Files" -msgstr "" +msgstr " קבצי×" #: editor/import_dock.cpp msgid "Import As:" -msgstr "" +msgstr "×™×™×‘×•× ×‘×ª×•×¨:" #: editor/import_dock.cpp editor/property_editor.cpp msgid "Preset.." -msgstr "" +msgstr "ערכה מוגדרת…" #: editor/import_dock.cpp msgid "Reimport" -msgstr "" +msgstr "×™×™×‘×•× ×ž×—×“×©" #: editor/multi_node_edit.cpp msgid "MultiNode Set" @@ -2782,40 +2776,40 @@ msgstr "" #: editor/node_dock.cpp msgid "Groups" -msgstr "" +msgstr "קבוצות" #: editor/node_dock.cpp msgid "Select a Node to edit Signals and Groups." -msgstr "" +msgstr "יש לבחור מפרק כדי לערוך ×ותות וקבוצות." #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create Poly" -msgstr "" +msgstr "יצירת מצולע" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/collision_polygon_editor_plugin.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Edit Poly" -msgstr "" +msgstr "עריכת מצולע" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Insert Point" -msgstr "" +msgstr "הוספת × ×§×•×“×”" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/collision_polygon_editor_plugin.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Edit Poly (Remove Point)" -msgstr "" +msgstr "עריכת מצולע (הסרת × ×§×•×“×”)" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Remove Poly And Point" -msgstr "" +msgstr "הסרת מצולע ×•× ×§×•×“×”" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Create a new polygon from scratch" -msgstr "" +msgstr "יצירת מצולע חדש מ×פס" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "" @@ -2827,7 +2821,7 @@ msgstr "" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Delete points" -msgstr "" +msgstr "מחיקת × ×§×•×“×•×ª" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" @@ -2835,7 +2829,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Animation Name:" -msgstr "" +msgstr "×©× ×”× ×¤×©×” חדשה:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Anim" @@ -3597,15 +3591,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4294,7 +4288,7 @@ msgstr "" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Delete Point" -msgstr "" +msgstr "מחיקת × ×§×•×“×”" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp @@ -4319,11 +4313,11 @@ msgstr "" #: editor/plugins/path_editor_plugin.cpp msgid "Split Path" -msgstr "" +msgstr "פיצול × ×ª×™×‘" #: editor/plugins/path_editor_plugin.cpp msgid "Remove Path Point" -msgstr "" +msgstr "הסרת × ×§×•×“×” ×‘× ×ª×™×‘" #: editor/plugins/path_editor_plugin.cpp msgid "Remove Out-Control Point" @@ -4347,31 +4341,31 @@ msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Move Point" -msgstr "" +msgstr "הזזת × ×§×•×“×”" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Ctrl: Rotate" -msgstr "" +msgstr "Ctrl: הטייה" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift: Move All" -msgstr "" +msgstr "Shift: הזזת הכול" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift+Ctrl: Scale" -msgstr "" +msgstr "Shift+Ctrl: ×§× ×” מידה" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Move Polygon" -msgstr "" +msgstr "הזזת מצולע" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Rotate Polygon" -msgstr "" +msgstr "הטיית מצולע" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Scale Polygon" -msgstr "" +msgstr "×©×™× ×•×™ ×§× ×” מידה של מצולע" #: editor/plugins/polygon_2d_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -4379,7 +4373,7 @@ msgstr "" #: editor/project_settings_editor.cpp editor/property_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Edit" -msgstr "" +msgstr "עריכה" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon->UV" @@ -4396,48 +4390,64 @@ msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap" -msgstr "" +msgstr "הצמדה" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Enable Snap" -msgstr "" +msgstr "הפעלת הצמדה" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid" -msgstr "" +msgstr "רשת" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "ERROR: Couldn't load resource!" -msgstr "" +msgstr "שגי××”: ×œ× × ×™×ª×Ÿ לטעון מש×ב!" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Add Resource" -msgstr "" +msgstr "הוספת מש×ב" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Rename Resource" -msgstr "" +msgstr "×©×™× ×•×™ ×©× ×ž×©×ב" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Delete Resource" -msgstr "" +msgstr "מחיקת מש×ב" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Resource clipboard is empty!" +msgstr "לוח גזירי המש××‘×™× ×¨×™×§!" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" -msgstr "" +msgstr "×˜×¢×™× ×ª מש×ב" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" -msgstr "" +msgstr "הדבקה" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "ResourcePreloader" @@ -4445,35 +4455,35 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Files" -msgstr "" +msgstr "מחיקת ×§×‘×¦×™× ××—×¨×•× ×™×" #: editor/plugins/script_editor_plugin.cpp msgid "Close and save changes?" -msgstr "" +msgstr "לסגור ולשמור ×ת ×”×©×™× ×•×™×™×?" #: editor/plugins/script_editor_plugin.cpp msgid "Error while saving theme" -msgstr "" +msgstr "שגי××” בשמירת ערכת העיצוב" #: editor/plugins/script_editor_plugin.cpp msgid "Error saving" -msgstr "" +msgstr "שגי××” בשמירה" #: editor/plugins/script_editor_plugin.cpp msgid "Error importing theme" -msgstr "" +msgstr "שגי××” ×‘×™×™×‘×•× ×¢×¨×›×ª ×”× ×•×©×" #: editor/plugins/script_editor_plugin.cpp msgid "Error importing" -msgstr "" +msgstr "שגי××” בייבו×" #: editor/plugins/script_editor_plugin.cpp msgid "Import Theme" -msgstr "" +msgstr "×™×™×‘×•× ×¢×¨×›×ª עיצוב" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme As.." -msgstr "" +msgstr "שמירת ערכת עיצוב בש×…" #: editor/plugins/script_editor_plugin.cpp msgid " Class Reference" @@ -4481,134 +4491,134 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "Sort" -msgstr "" +msgstr "מיון" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Move Up" -msgstr "" +msgstr "העברה למעלה" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Move Down" -msgstr "" +msgstr "העברה למטה" #: editor/plugins/script_editor_plugin.cpp msgid "Next script" -msgstr "" +msgstr "הסקריפט הב×" #: editor/plugins/script_editor_plugin.cpp msgid "Previous script" -msgstr "" +msgstr "הסקריפט הקוד×" #: editor/plugins/script_editor_plugin.cpp msgid "File" -msgstr "" +msgstr "קובץ" #: editor/plugins/script_editor_plugin.cpp msgid "New" -msgstr "" +msgstr "חדש" #: editor/plugins/script_editor_plugin.cpp msgid "Save All" -msgstr "" +msgstr "לשמור הכול" #: editor/plugins/script_editor_plugin.cpp msgid "Soft Reload Script" -msgstr "" +msgstr "סקריפט ×¨×¢× ×•×Ÿ רך" #: editor/plugins/script_editor_plugin.cpp msgid "Copy Script Path" -msgstr "" +msgstr "העתקת × ×ª×™×‘ הסקריפט" #: editor/plugins/script_editor_plugin.cpp msgid "Show In File System" -msgstr "" +msgstr "הצגה במערכת הקבצי×" #: editor/plugins/script_editor_plugin.cpp msgid "History Prev" -msgstr "" +msgstr "×”×§×•×“× ×‘×”×™×¡×˜×•×¨×™×”" #: editor/plugins/script_editor_plugin.cpp msgid "History Next" -msgstr "" +msgstr "×”×‘× ×‘×”×™×¡×˜×•×¨×™×”" #: editor/plugins/script_editor_plugin.cpp msgid "Reload Theme" -msgstr "" +msgstr "×¨×¢× ×•×Ÿ ערכת העיצוב" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme" -msgstr "" +msgstr "שמירת ערכת העיצוב" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme As" -msgstr "" +msgstr "שמירת ערכת העיצוב בש×" #: editor/plugins/script_editor_plugin.cpp msgid "Close Docs" -msgstr "" +msgstr "סגירת מסמכי×" #: editor/plugins/script_editor_plugin.cpp msgid "Close All" -msgstr "" +msgstr "לסגור הכול" #: editor/plugins/script_editor_plugin.cpp msgid "Close Other Tabs" -msgstr "" +msgstr "לסגור ×œ×©×•× ×™×•×ª ×חרות" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp msgid "Run" -msgstr "" +msgstr "הרצה" #: editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" -msgstr "" +msgstr "החלפת תצוגת ×—×œ×•× ×™×ª סקריפטי×" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find.." -msgstr "" +msgstr "×יתור…" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find Next" -msgstr "" +msgstr "×יתור הב×" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Over" -msgstr "" +msgstr "לצעוד מעל" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" -msgstr "" +msgstr "לצעוד לתוך" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Break" -msgstr "" +msgstr "עצירה" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp #: editor/script_editor_debugger.cpp msgid "Continue" -msgstr "" +msgstr "המשך" #: editor/plugins/script_editor_plugin.cpp msgid "Keep Debugger Open" -msgstr "" +msgstr "להש×יר ×ת ×ž× ×¤×” השגי×ות פתוח" #: editor/plugins/script_editor_plugin.cpp msgid "Debug with external editor" -msgstr "" +msgstr "× ×™×¤×•×™ שגי×ות ×¢× ×¢×•×¨×š ×—×™×¦×•× ×™" #: editor/plugins/script_editor_plugin.cpp msgid "Open Godot online documentation" -msgstr "" +msgstr "פתיחת התיעוד המקוון של Godot" #: editor/plugins/script_editor_plugin.cpp msgid "Search the class hierarchy." -msgstr "" +msgstr "חיפוש בהיררכיית המחלקות." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -4616,114 +4626,116 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "Go to previous edited document." -msgstr "" +msgstr "מעבר למסמך ×”×§×•×“× ×©× ×¢×¨×š." #: editor/plugins/script_editor_plugin.cpp msgid "Go to next edited document." -msgstr "" +msgstr "מעבר למסמך ×”×‘× ×©× ×¢×¨×š." #: editor/plugins/script_editor_plugin.cpp msgid "Discard" -msgstr "" +msgstr "התעלמות" #: editor/plugins/script_editor_plugin.cpp msgid "Create Script" -msgstr "" +msgstr "יצירת סקריפט" #: editor/plugins/script_editor_plugin.cpp msgid "" "The following files are newer on disk.\n" "What action should be taken?:" msgstr "" +"×”×§×‘×¦×™× ×”×‘××™× ×”× ×—×“×©×™× ×‘×›×•× ×Ÿ.\n" +"ב×ילו פעולות ×œ× ×§×•×˜?:" #: editor/plugins/script_editor_plugin.cpp msgid "Reload" -msgstr "" +msgstr "×¨×¢× ×•×Ÿ" #: editor/plugins/script_editor_plugin.cpp msgid "Resave" -msgstr "" +msgstr "שמירה מחדש" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" -msgstr "" +msgstr "×ž× ×¤×” שגי×ות" #: editor/plugins/script_editor_plugin.cpp msgid "" "Built-in scripts can only be edited when the scene they belong to is loaded" -msgstr "" +msgstr "× ×™×ª×Ÿ לערוך ×¡×§×¨×™×¤×˜×™× ×ž×•×‘× ×™× ×¨×§ ×›×שר ×”×¡×¦× ×” ××œ×™×”× ×”× ×©×™×™×›×™× × ×˜×¢× ×”" #: editor/plugins/script_text_editor.cpp msgid "Only resources from filesystem can be dropped." -msgstr "" +msgstr "× ×™×ª×Ÿ להשמיט מש××‘×™× ×ž×ž×¢×¨×›×ª ×”×§×‘×¦×™× ×‘×œ×‘×“." #: editor/plugins/script_text_editor.cpp msgid "Pick Color" -msgstr "" +msgstr "בחירת צבע" #: editor/plugins/script_text_editor.cpp msgid "Convert Case" -msgstr "" +msgstr "החלפת מצב רשיות" #: editor/plugins/script_text_editor.cpp msgid "Uppercase" -msgstr "" +msgstr "×ותיות גדולות" #: editor/plugins/script_text_editor.cpp msgid "Lowercase" -msgstr "" +msgstr "×ותיות ×§×˜× ×•×ª" #: editor/plugins/script_text_editor.cpp msgid "Capitalize" -msgstr "" +msgstr "הגדלת ×ות ר××©×•× ×”" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" -msgstr "" +msgstr "גזירה" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" -msgstr "" +msgstr "העתקה" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Select All" -msgstr "" +msgstr "לבחור הכול" #: editor/plugins/script_text_editor.cpp msgid "Delete Line" -msgstr "" +msgstr "מחיקת שורה" #: editor/plugins/script_text_editor.cpp msgid "Indent Left" -msgstr "" +msgstr "×”×–×—×” משמ×ל" #: editor/plugins/script_text_editor.cpp msgid "Indent Right" -msgstr "" +msgstr "×”×–×—×” מימין" #: editor/plugins/script_text_editor.cpp msgid "Toggle Comment" -msgstr "" - -#: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" +msgstr "החלפת מצב הערה" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" -msgstr "" +msgstr "צמצו×/הרחבה של שורה" #: editor/plugins/script_text_editor.cpp msgid "Fold All Lines" -msgstr "" +msgstr "×¦×ž×¦×•× ×›×œ השורות" #: editor/plugins/script_text_editor.cpp msgid "Unfold All Lines" -msgstr "" +msgstr "הרחבת כל השורות" + +#: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "לשכפל למטה" #: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" @@ -4735,60 +4747,60 @@ msgstr "" #: editor/plugins/script_text_editor.cpp msgid "Convert Indent To Spaces" -msgstr "" +msgstr "המרת הזחות לרווחי×" #: editor/plugins/script_text_editor.cpp msgid "Convert Indent To Tabs" -msgstr "" +msgstr "המרת הזחות לט×בי×" #: editor/plugins/script_text_editor.cpp msgid "Auto Indent" -msgstr "" +msgstr "×”×–×—×” ×וטומטית" #: editor/plugins/script_text_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Toggle Breakpoint" -msgstr "" +msgstr "החלפת מצב × ×§×•×“×ª עצירה" #: editor/plugins/script_text_editor.cpp msgid "Remove All Breakpoints" -msgstr "" +msgstr "הסרת כל × ×§×•×“×•×ª העצירה" #: editor/plugins/script_text_editor.cpp msgid "Goto Next Breakpoint" -msgstr "" +msgstr "מעבר ×œ× ×§×•×“×ª העצירה הב××”" #: editor/plugins/script_text_editor.cpp msgid "Goto Previous Breakpoint" -msgstr "" +msgstr "מעבר ×œ× ×§×•×“×ª העצירה הקודמת" #: editor/plugins/script_text_editor.cpp msgid "Convert To Uppercase" -msgstr "" +msgstr "המרה ל×ותיות גדולות" #: editor/plugins/script_text_editor.cpp msgid "Convert To Lowercase" -msgstr "" +msgstr "המרה ל×ותיות ×§×˜× ×•×ª" #: editor/plugins/script_text_editor.cpp msgid "Find Previous" -msgstr "" +msgstr "×יתור הקוד×" #: editor/plugins/script_text_editor.cpp msgid "Replace.." -msgstr "" +msgstr "החלפה…" #: editor/plugins/script_text_editor.cpp msgid "Goto Function.." -msgstr "" +msgstr "מעבר ×œ×¤×•× ×§×¦×™×”â€¦" #: editor/plugins/script_text_editor.cpp msgid "Goto Line.." -msgstr "" +msgstr "מעבר לשורה…" #: editor/plugins/script_text_editor.cpp msgid "Contextual Help" -msgstr "" +msgstr "עזרה תלוית הקשר" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -4848,7 +4860,7 @@ msgstr "" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Default Value" -msgstr "" +msgstr "×©×™× ×•×™ ערך בררת המחדל" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change XForm Uniform" @@ -4864,7 +4876,7 @@ msgstr "" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Comment" -msgstr "" +msgstr "×©×™× ×•×™ הערה" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Add/Remove to Color Ramp" @@ -4880,7 +4892,7 @@ msgstr "" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Input Name" -msgstr "" +msgstr "×©×™× ×•×™ ×©× ×§×œ×˜" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Connect Graph Nodes" @@ -4912,7 +4924,7 @@ msgstr "" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Error: Missing Input Connections" -msgstr "" +msgstr "שגי××”: ×—×¡×¨×™× ×—×™×‘×•×¨×™ קלט" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Add Shader Graph Node" @@ -4956,7 +4968,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotating %s degrees." -msgstr "" +msgstr "הטיה של %s מעלות." #: editor/plugins/spatial_editor_plugin.cpp msgid "Keying is disabled (no key inserted)." @@ -4972,7 +4984,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Material Changes" -msgstr "" +msgstr "×©×™× ×•×™×™ חומרי×" #: editor/plugins/spatial_editor_plugin.cpp msgid "Shader Changes" @@ -4988,7 +5000,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Vertices" -msgstr "" +msgstr "קודקודי×" #: editor/plugins/spatial_editor_plugin.cpp msgid "FPS" @@ -4996,55 +5008,55 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Top View." -msgstr "" +msgstr "מבט על." #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom View." -msgstr "" +msgstr "מבט מתחת." #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom" -msgstr "" +msgstr "מתחת" #: editor/plugins/spatial_editor_plugin.cpp msgid "Left View." -msgstr "" +msgstr "מבט משמ×ל." #: editor/plugins/spatial_editor_plugin.cpp msgid "Left" -msgstr "" +msgstr "שמ×ל" #: editor/plugins/spatial_editor_plugin.cpp msgid "Right View." -msgstr "" +msgstr "מבט מימין." #: editor/plugins/spatial_editor_plugin.cpp msgid "Right" -msgstr "" +msgstr "ימין" #: editor/plugins/spatial_editor_plugin.cpp msgid "Front View." -msgstr "" +msgstr "מבט קדמי." #: editor/plugins/spatial_editor_plugin.cpp msgid "Front" -msgstr "" +msgstr "קדמי" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rear View." -msgstr "" +msgstr "מבט ×חורי." #: editor/plugins/spatial_editor_plugin.cpp msgid "Rear" -msgstr "" +msgstr "×חורי" #: editor/plugins/spatial_editor_plugin.cpp msgid "Align with view" -msgstr "" +msgstr "יישור ×¢× ×”×ª×¦×•×’×”" #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "OK :(" -msgstr "" +msgstr "בסדר :(" #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "No parent to instance a child at." @@ -5056,15 +5068,15 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Normal" -msgstr "" +msgstr "הצגה × ×•×¨×ž×œ×™×ª" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Wireframe" -msgstr "" +msgstr "הצגת מסגרת קווי×" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Overdraw" -msgstr "" +msgstr "הצגת שכבת פירוט" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Unshaded" @@ -5072,7 +5084,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Environment" -msgstr "" +msgstr "צפייה בסביבה" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Gizmos" @@ -5080,7 +5092,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Information" -msgstr "" +msgstr "הצגת מידע" #: editor/plugins/spatial_editor_plugin.cpp msgid "View FPS" @@ -5088,11 +5100,11 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Half Resolution" -msgstr "" +msgstr "חצי רזולוציה" #: editor/plugins/spatial_editor_plugin.cpp msgid "Audio Listener" -msgstr "" +msgstr "מ×זין לשמע" #: editor/plugins/spatial_editor_plugin.cpp msgid "Doppler Enable" @@ -5132,7 +5144,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Select Mode (Q)" -msgstr "" +msgstr "בחירת מצב (Q)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -5140,58 +5152,61 @@ msgid "" "Alt+Drag: Move\n" "Alt+RMB: Depth list selection" msgstr "" +"גרירה: הטיה\n" +"Alt+גרירה: ×”×–×–×”\n" +"Alt+כפתור ×™×ž× ×™: בחירת רשימת עומק" #: editor/plugins/spatial_editor_plugin.cpp msgid "Move Mode (W)" -msgstr "" +msgstr "מצב ×”×–×–×” (W)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotate Mode (E)" -msgstr "" +msgstr "מצב הטיה (E)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale Mode (R)" -msgstr "" +msgstr "מצב ×©×™× ×•×™ ×§× ×” מידה (R)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Local Coords" -msgstr "" +msgstr "× ×§×•×“×•×ª ציון מקומיות" #: editor/plugins/spatial_editor_plugin.cpp msgid "Local Space Mode (%s)" -msgstr "" +msgstr "מצב מרחב מקומי (%s)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Mode (%s)" -msgstr "" +msgstr "מצב הצמדה (%s)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom View" -msgstr "" +msgstr "מבט תחתי" #: editor/plugins/spatial_editor_plugin.cpp msgid "Top View" -msgstr "" +msgstr "מבט על" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rear View" -msgstr "" +msgstr "מבט ×חורי" #: editor/plugins/spatial_editor_plugin.cpp msgid "Front View" -msgstr "" +msgstr "מבט קדמי" #: editor/plugins/spatial_editor_plugin.cpp msgid "Left View" -msgstr "" +msgstr "מבט שמ×לי" #: editor/plugins/spatial_editor_plugin.cpp msgid "Right View" -msgstr "" +msgstr "מבט ×™×ž× ×™" #: editor/plugins/spatial_editor_plugin.cpp msgid "Switch Perspective/Orthogonal view" -msgstr "" +msgstr "החלפה בין תצוגה פרספקטיבה/×× ×›×™×ª" #: editor/plugins/spatial_editor_plugin.cpp msgid "Insert Animation Key" @@ -5203,7 +5218,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Focus Selection" -msgstr "" +msgstr "בחירת מיקוד" #: editor/plugins/spatial_editor_plugin.cpp msgid "Align Selection With View" @@ -5227,15 +5242,15 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Toggle Freelook" -msgstr "" +msgstr "החלפת מצב מבט חופשי" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform" -msgstr "" +msgstr "התמרה" #: editor/plugins/spatial_editor_plugin.cpp msgid "Configure Snap.." -msgstr "" +msgstr "הגדרת הצמדה…" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Dialog.." @@ -5276,7 +5291,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Settings" -msgstr "" +msgstr "הגדרות" #: editor/plugins/spatial_editor_plugin.cpp msgid "Skeleton Gizmo visibility" @@ -5284,7 +5299,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Settings" -msgstr "" +msgstr "הגדרות הצמדה" #: editor/plugins/spatial_editor_plugin.cpp msgid "Translate Snap:" @@ -5324,11 +5339,11 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotate (deg.):" -msgstr "" +msgstr "הטיה (מעלות):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale (ratio):" -msgstr "" +msgstr "×©×™× ×•×™ ×§× ×” מידה (יחס):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Type" @@ -5376,19 +5391,19 @@ msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Animations" -msgstr "" +msgstr "×”× ×¤×©×•×ª" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed (FPS):" -msgstr "" +msgstr "מהירות (FPS):" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Loop" -msgstr "" +msgstr "לול××”" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Animation Frames" -msgstr "" +msgstr "שקופיות ×”×”× ×¤×©×”" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -5566,11 +5581,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5830,10 +5840,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5854,7 +5860,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5874,10 +5882,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6565,10 +6569,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6678,10 +6678,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7104,11 +7100,25 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +#, fuzzy +msgid "Next Plane" +msgstr "×”×œ×©×•× ×™×ª הב××”" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "Previous Plane" +msgstr "×”×œ×©×•× ×™×ª הקודמת" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7116,19 +7126,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7145,59 +7155,59 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Edit X Axis" -msgstr "" +msgstr "עריכת ציר X" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Edit Y Axis" -msgstr "" +msgstr "עריכת ציר Y" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Edit Z Axis" -msgstr "" +msgstr "עריכת ציר Z" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Rotate X" -msgstr "" +msgstr "הטיית מצביע ב־X" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Rotate Y" -msgstr "" +msgstr "הטיית מצביע ב־Y" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Rotate Z" -msgstr "" +msgstr "הטיית מצביע ב־Z" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Back Rotate X" -msgstr "" +msgstr "הטיית מצביע הפוכה ב־X" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Back Rotate Y" -msgstr "" +msgstr "הטיית מצביע הפוכה ב־Y" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Back Rotate Z" -msgstr "" +msgstr "הטיית מצביע הפוכה ב־Z" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Clear Rotation" -msgstr "" +msgstr "מחיקת הטיית מצביע" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Create Area" -msgstr "" +msgstr "יצירת שטח" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Create Exterior Connector" -msgstr "" +msgstr "יצירת מחבר ×—×™×¦×•× ×™" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Erase Area" -msgstr "" +msgstr "מחיקת שטח" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clear Selection" -msgstr "" +msgstr "ביטול הבחירה" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Settings" @@ -7205,40 +7215,44 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Pick Distance:" -msgstr "" +msgstr "בחירת מרחק:" #: modules/mono/editor/godotsharp_editor.cpp msgid "Generating solution..." -msgstr "" +msgstr "הפתרון × ×•×¦×¨â€¦" #: modules/mono/editor/godotsharp_editor.cpp msgid "Generating C# project..." -msgstr "" +msgstr "× ×•×¦×¨ ×ž×™×–× C#‎…" #: modules/mono/editor/godotsharp_editor.cpp msgid "Failed to create solution." -msgstr "" +msgstr "יצירת הפתרון × ×›×©×œ×”." #: modules/mono/editor/godotsharp_editor.cpp msgid "Failed to save solution." -msgstr "" +msgstr "שמירת הפתרון × ×›×©×œ×”." #: modules/mono/editor/godotsharp_editor.cpp msgid "Done" -msgstr "" +msgstr "בוצע" #: modules/mono/editor/godotsharp_editor.cpp msgid "Failed to create C# project." -msgstr "" +msgstr "יצירת ×ž×™×–× C#‎ × ×›×©×œ×”." #: modules/mono/editor/godotsharp_editor.cpp msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" +msgid "About C# support" msgstr "" +#: modules/mono/editor/godotsharp_editor.cpp +msgid "Create C# solution" +msgstr "יצירת פתרון C#‎" + #: modules/mono/editor/mono_bottom_panel.cpp msgid "Builds" msgstr "" @@ -7249,6 +7263,10 @@ msgstr "" #: modules/mono/editor/mono_bottom_panel.cpp msgid "Warnings" +msgstr "×זהרות" + +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" msgstr "" #: modules/visual_script/visual_script.cpp @@ -7751,6 +7769,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin דורש מפרק צ××¦× ×ž×¡×•×’ ARVRCamera" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -7912,6 +7938,9 @@ msgstr "שגי××” ×‘×˜×¢×™× ×ª הגופן." msgid "Invalid font size." msgstr "גודל הגופן שגוי." +#~ msgid "Can't write file." +#~ msgstr "×œ× × ×™×ª×Ÿ לכתוב קובץ." + #~ msgid "Next" #~ msgstr "הב×" diff --git a/editor/translations/hi.po b/editor/translations/hi.po index c124727d74..cba5b3059b 100644 --- a/editor/translations/hi.po +++ b/editor/translations/hi.po @@ -2405,12 +2405,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2463,10 +2457,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3637,15 +3627,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4468,6 +4458,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4751,10 +4757,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "" @@ -4767,6 +4769,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5607,11 +5613,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5871,10 +5872,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5895,7 +5892,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5915,10 +5914,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6609,10 +6604,6 @@ msgstr "संसाधन" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6722,10 +6713,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7148,11 +7135,23 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +msgid "Next Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7160,19 +7159,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7280,6 +7279,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "सदसà¥à¤¯à¤¤à¤¾ बनाà¤à¤‚" @@ -7296,6 +7299,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7795,6 +7802,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/editor/translations/hu.po b/editor/translations/hu.po index 9d89e98f7e..3b728caafc 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-01-20 08:54+0000\n" +"PO-Revision-Date: 2018-02-24 12:37+0000\n" "Last-Translator: Varga Dániel <danikah.danikah@gmail.com>\n" "Language-Team: Hungarian <https://hosted.weblate.org/projects/godot-engine/" "godot/hu/>\n" @@ -18,7 +18,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -26,7 +26,7 @@ msgstr "Tiltva" #: editor/animation_editor.cpp msgid "All Selection" -msgstr "Mind kiválasztva" +msgstr "Minden Kiválasztás" #: editor/animation_editor.cpp msgid "Anim Change Keyframe Time" @@ -143,7 +143,7 @@ msgstr "Ãtméretezés A Kurzortól" #: editor/animation_editor.cpp msgid "Goto Next Step" -msgstr "Ugrás A következÅ‘ lépésre" +msgstr "Ugrás A KövetkezÅ‘ Lépésre" #: editor/animation_editor.cpp msgid "Goto Prev Step" @@ -152,7 +152,7 @@ msgstr "Ugrás Az ElÅ‘zÅ‘ Lépésre" #: editor/animation_editor.cpp editor/plugins/curve_editor_plugin.cpp #: editor/property_editor.cpp msgid "Linear" -msgstr "Egyenes irányú" +msgstr "Lineáris" #: editor/animation_editor.cpp editor/plugins/theme_editor_plugin.cpp msgid "Constant" @@ -188,7 +188,7 @@ msgstr "Animáció MegtisztÃtása" #: editor/animation_editor.cpp msgid "Create NEW track for %s and insert key?" -msgstr "Létrehoz ÚJ útvonalat %s -hez és beilleszti a kulcsot?" +msgstr "Létrehoz ÚJ nyomvonalat %s -hez és beilleszti a kulcsot?" #: editor/animation_editor.cpp msgid "Create %d NEW tracks and insert keys?" @@ -208,7 +208,7 @@ msgstr "Animáció Létrehozása És Beillesztése" #: editor/animation_editor.cpp msgid "Anim Insert Track & Key" -msgstr "Animáció Útvonal És Kulcs Beillesztése" +msgstr "Animáció Nyomvonal És Kulcs Beillesztése" #: editor/animation_editor.cpp msgid "Anim Insert Key" @@ -216,7 +216,7 @@ msgstr "Animáció Kulcs Beillesztése" #: editor/animation_editor.cpp msgid "Change Anim Len" -msgstr "Csak Animáció változtatása" +msgstr "Animáció Hossz Változtatása" #: editor/animation_editor.cpp msgid "Change Anim Loop" @@ -426,7 +426,7 @@ msgid "" "Node." msgstr "" "Nem található a cél metódus! Nevezzen meg egy érvényes metódust, vagy " -"csatoljon egy scriptet a cél Node-hoz." +"csatoljon egy szkriptet a cél Node-hoz." #: editor/connections_dialog.cpp msgid "Connect To Node:" @@ -519,7 +519,7 @@ msgstr "%s TÃpusának Megváltoztatása" #: editor/create_dialog.cpp editor/project_settings_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Change" -msgstr "Megváltoztatás" +msgstr "Változtatás" #: editor/create_dialog.cpp msgid "Create New %s" @@ -633,7 +633,6 @@ msgstr "" "EltávolÃtja Å‘ket ennek ellenére? (nem visszavonható)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Cannot remove:" msgstr "Nem eltávolÃtható:" @@ -719,7 +718,7 @@ msgstr "VezetÅ‘ FejlesztÅ‘" #: editor/editor_about.cpp msgid "Project Manager " -msgstr "Projekt Menedzser " +msgstr "Projekt KezelÅ‘ " #: editor/editor_about.cpp msgid "Developers" @@ -828,9 +827,8 @@ msgid "Rename Audio Bus" msgstr "Hangbusz Ãtnevezése" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Change Audio Bus Volume" -msgstr "Tömb értékének megváltoztatása" +msgstr "Hangbusz HangerÅ‘ MódosÃtás" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Solo" @@ -1328,19 +1326,18 @@ msgid "Description" msgstr "LeÃrás" #: editor/editor_help.cpp -#, fuzzy msgid "Online Tutorials:" -msgstr "Online Dokumentáció" +msgstr "Online Oktatóanyagok:" #: editor/editor_help.cpp -#, fuzzy msgid "" "There are currently no tutorials for this class, you can [color=$color][url=" "$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/" "url][/color]." msgstr "" -"Ennek a metódusnak jelenleg nincs leÃrása. SegÃtsen minket azzal, hogy " -"[color=$color][url=$url]hozzájárul eggyel[/url][/color]!" +"Jelenleg nincsenek oktatóanyagok ehhez az osztályhoz. [color=$color][url=" +"$url]Hozzájárulhat eggyel[/url][/color], vagy [color=$color][url=" +"$url2]kérvényezhet egyet[/url][/color]." #: editor/editor_help.cpp msgid "Properties" @@ -1566,7 +1563,7 @@ msgstr "Összes tulajdonság összecsukása" #: editor/editor_node.cpp msgid "Copy Params" -msgstr "Paraméterek másolása" +msgstr "Paraméterek Másolása" #: editor/editor_node.cpp msgid "Paste Params" @@ -1578,7 +1575,7 @@ msgstr "ErÅ‘forrás Beillesztése" #: editor/editor_node.cpp msgid "Copy Resource" -msgstr "Forrás másolása" +msgstr "ErÅ‘forrás Másolása" #: editor/editor_node.cpp msgid "Make Built-In" @@ -1651,7 +1648,7 @@ msgstr "Jelenet Gyors Megnyitása.." #: editor/editor_node.cpp msgid "Quick Open Script.." -msgstr "Script Gyors Megnyitása.." +msgstr "Szkript Gyors Megnyitása.." #: editor/editor_node.cpp msgid "Save & Close" @@ -1765,25 +1762,25 @@ msgstr "" #: editor/editor_node.cpp msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." msgstr "" -"Nem található script mezÅ‘ az addon pluginnak a következÅ‘ helyen: 'res://" +"Nem található szkript mezÅ‘ az addon pluginnak a következÅ‘ helyen: 'res://" "addons/%s'." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." -msgstr "Nem sikerült az addon script betöltése a következÅ‘ útvonalról: '%s'." +msgstr "Nem sikerült az addon szkript betöltése a következÅ‘ útvonalról: '%s'." #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' Base type is not EditorPlugin." msgstr "" -"Nem sikerült az addon script betöltése a következÅ‘ útvonalról: '%s' Az " +"Nem sikerült az addon szkript betöltése a következÅ‘ útvonalról: '%s' Az " "alaptÃpus nem EditorPlugin." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s' Script is not in tool mode." msgstr "" -"Nem sikerült az addon script betöltése a következÅ‘ útvonalról: '%s' A script " -"nem eszközmódban van." +"Nem sikerült az addon szkript betöltése a következÅ‘ útvonalról: '%s' A " +"szkript nem eszközmódban van." #: editor/editor_node.cpp msgid "" @@ -1953,7 +1950,7 @@ msgstr "Projekt BeállÃtások" #: editor/editor_node.cpp msgid "Run Script" -msgstr "Script Futtatása" +msgstr "Szkript Futtatása" #: editor/editor_node.cpp editor/project_export.cpp msgid "Export" @@ -2045,7 +2042,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Sync Script Changes" -msgstr "Script Változtatások Szinkronizálása" +msgstr "Szkript Változtatások Szinkronizálása" #: editor/editor_node.cpp msgid "" @@ -2054,7 +2051,7 @@ msgid "" "When used remotely on a device, this is more efficient with network " "filesystem." msgstr "" -"Ha ez a beállÃtás be van kapcsolva, bármilyen script, amit elment, újra " +"Ha ez a beállÃtás be van kapcsolva, bármilyen szkript, amit elment, újra " "betöltÅ‘dik a futó játékba.\n" "Ha egy távoli eszközön használja, sokkal hatékonyabb a hálózati " "fájlrendszerrel együtt." @@ -2253,7 +2250,7 @@ msgstr "Jelszó:" #: editor/editor_node.cpp msgid "Open & Run a Script" -msgstr "Megnyit és Scriptet Futtat" +msgstr "Szkriptet Megnyit és Futtat" #: editor/editor_node.cpp msgid "New Inherited" @@ -2277,7 +2274,7 @@ msgstr "3D SzerkesztÅ‘ Megnyitása" #: editor/editor_node.cpp msgid "Open Script Editor" -msgstr "Script SzerkesztÅ‘ Megnyitása" +msgstr "Szkript SzerkesztÅ‘ Megnyitása" #: editor/editor_node.cpp editor/project_manager.cpp msgid "Open Asset Library" @@ -2293,625 +2290,621 @@ msgstr "ElÅ‘zÅ‘ SzerkesztÅ‘ Megnyitása" #: editor/editor_plugin.cpp msgid "Creating Mesh Previews" -msgstr "" +msgstr "Háló ElÅ‘nézetek Létrehozása" #: editor/editor_plugin.cpp msgid "Thumbnail.." -msgstr "" +msgstr "Indexkép.." #: editor/editor_plugin_settings.cpp msgid "Installed Plugins:" -msgstr "" +msgstr "TelepÃtett BÅ‘vÃtmények:" #: editor/editor_plugin_settings.cpp msgid "Update" -msgstr "" +msgstr "FrissÃtés" #: editor/editor_plugin_settings.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Version:" -msgstr "" +msgstr "Verzió:" #: editor/editor_plugin_settings.cpp msgid "Author:" -msgstr "" +msgstr "SzerzÅ‘:" #: editor/editor_plugin_settings.cpp msgid "Status:" -msgstr "" +msgstr "Ãllapot:" #: editor/editor_profiler.cpp msgid "Stop Profiling" -msgstr "" +msgstr "Profilozás LeállÃtása" #: editor/editor_profiler.cpp msgid "Start Profiling" -msgstr "" +msgstr "Profilozás IndÃtása" #: editor/editor_profiler.cpp msgid "Measure:" -msgstr "" +msgstr "Mérés:" #: editor/editor_profiler.cpp msgid "Frame Time (sec)" -msgstr "" +msgstr "KeretidÅ‘ (mp)" #: editor/editor_profiler.cpp msgid "Average Time (sec)" -msgstr "" +msgstr "Ãtlagos IdÅ‘ (mp)" #: editor/editor_profiler.cpp msgid "Frame %" -msgstr "" +msgstr "Keret %" #: editor/editor_profiler.cpp msgid "Physics Frame %" -msgstr "" +msgstr "Fizika Keret %" #: editor/editor_profiler.cpp editor/script_editor_debugger.cpp msgid "Time:" -msgstr "" +msgstr "IdÅ‘:" #: editor/editor_profiler.cpp msgid "Inclusive" -msgstr "" +msgstr "Befoglaló" #: editor/editor_profiler.cpp msgid "Self" -msgstr "" +msgstr "Saját" #: editor/editor_profiler.cpp msgid "Frame #:" -msgstr "" +msgstr "Keret #:" #: editor/editor_profiler.cpp msgid "Time" -msgstr "" +msgstr "IdÅ‘" #: editor/editor_profiler.cpp msgid "Calls" -msgstr "" +msgstr "HÃvások" #: editor/editor_run_native.cpp msgid "Select device from the list" -msgstr "" +msgstr "Válasszon készüléket a listából" #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" "Please add a runnable preset in the export menu." msgstr "" +"Nem található futtatható exportállomány ehhez a platformhoz.\n" +"Adjon hozzá egy futtatható exportállományt az export menüben." #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." -msgstr "" +msgstr "Ãrja a logikát a _run() metódusba." #: editor/editor_run_script.cpp msgid "There is an edited scene already." -msgstr "" +msgstr "Már létezik szerkesztett jelenet." #: editor/editor_run_script.cpp msgid "Couldn't instance script:" -msgstr "" +msgstr "Nem sikerült a szkript példányosÃtása:" #: editor/editor_run_script.cpp msgid "Did you forget the 'tool' keyword?" -msgstr "" +msgstr "Nem felejtette el a 'tool' kulcsszót?" #: editor/editor_run_script.cpp msgid "Couldn't run script:" -msgstr "" +msgstr "Nem sikerült a szkript futtatása:" #: editor/editor_run_script.cpp msgid "Did you forget the '_run' method?" -msgstr "" +msgstr "Nem felejtette el a '_run' metódust?" #: editor/editor_settings.cpp msgid "Default (Same as Editor)" -msgstr "" +msgstr "Alapértelmezett (Ugyanaz, Mint a SzerkesztÅ‘nek)" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" -msgstr "" +msgstr "Válassza Ki Az Importálandó Node-okat" #: editor/editor_sub_scene.cpp msgid "Scene Path:" -msgstr "" +msgstr "Jelenet Elérési Útja:" #: editor/editor_sub_scene.cpp msgid "Import From Node:" -msgstr "" +msgstr "Importálás Node-ból:" #: editor/export_template_manager.cpp msgid "Re-Download" -msgstr "" +msgstr "Letöltés Megint" #: editor/export_template_manager.cpp msgid "Uninstall" -msgstr "" +msgstr "EltávolÃtás" #: editor/export_template_manager.cpp msgid "(Installed)" -msgstr "" +msgstr "(TelepÃtve)" #: editor/export_template_manager.cpp msgid "Download" -msgstr "" +msgstr "Letöltés" #: editor/export_template_manager.cpp msgid "(Missing)" -msgstr "" +msgstr "(Hiányzik)" #: editor/export_template_manager.cpp msgid "(Current)" -msgstr "" +msgstr "(Jelenlegi)" #: editor/export_template_manager.cpp msgid "Retrieving mirrors, please wait.." -msgstr "" +msgstr "Tükrök letöltése, kérjük várjon.." #: editor/export_template_manager.cpp msgid "Remove template version '%s'?" -msgstr "" +msgstr "EltávolÃtja a(z) '%s' verziójú sablont?" #: editor/export_template_manager.cpp msgid "Can't open export templates zip." -msgstr "" +msgstr "Nem nyitható meg az export sablon zip." #: editor/export_template_manager.cpp msgid "Invalid version.txt format inside templates." -msgstr "" - -#: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" +msgstr "Érvénytelen version.txt formátum a sablonokban." #: editor/export_template_manager.cpp msgid "No version.txt found inside templates." -msgstr "" +msgstr "Nem található version.txt a sablonokban." #: editor/export_template_manager.cpp msgid "Error creating path for templates:" -msgstr "" +msgstr "Hiba történt a sablonok elérési útjának létrehozásakor:" #: editor/export_template_manager.cpp msgid "Extracting Export Templates" -msgstr "" +msgstr "Export Sablonok Kibontása" #: editor/export_template_manager.cpp msgid "Importing:" -msgstr "" +msgstr "Importálás:" #: editor/export_template_manager.cpp msgid "" "No download links found for this version. Direct download is only available " "for official releases." msgstr "" +"Nem található letöltési link ehhez a verzióhoz. Közvetlen letöltés csak a " +"hivatalos kiadásokhoz elérhetÅ‘." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve." -msgstr "" +msgstr "Nem megoldható." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't connect." -msgstr "" +msgstr "Nem lehet csatlakozni." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "No response." -msgstr "" +msgstr "Nincs válasz." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request Failed." -msgstr "" +msgstr "Kérés Sikertelen." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Redirect Loop." -msgstr "" +msgstr "ÃtirányÃtási Hurok." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed:" -msgstr "" - -#: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" +msgstr "Sikertelen:" #: editor/export_template_manager.cpp msgid "Download Complete." -msgstr "" +msgstr "A Letöltés BefejezÅ‘dött." #: editor/export_template_manager.cpp msgid "Error requesting url: " -msgstr "" +msgstr "Hiba történt az url lekérdezésekor: " #: editor/export_template_manager.cpp msgid "Connecting to Mirror.." -msgstr "" +msgstr "Csatlakozás Tükörhöz.." #: editor/export_template_manager.cpp msgid "Disconnected" -msgstr "" +msgstr "Kapcsolat bontva" #: editor/export_template_manager.cpp msgid "Resolving" -msgstr "" +msgstr "Megoldás" #: editor/export_template_manager.cpp msgid "Can't Resolve" -msgstr "" +msgstr "Nem Megoldható" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connecting.." -msgstr "" +msgstr "Csatlakozás.." #: editor/export_template_manager.cpp -#, fuzzy msgid "Can't Connect" -msgstr "Kapcsolódás..." +msgstr "Nem Lehet Csatlakozni" #: editor/export_template_manager.cpp msgid "Connected" -msgstr "" +msgstr "Csatlakozva" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Requesting.." -msgstr "" +msgstr "Lekérdezés.." #: editor/export_template_manager.cpp msgid "Downloading" -msgstr "" +msgstr "Letöltés" #: editor/export_template_manager.cpp msgid "Connection Error" -msgstr "" +msgstr "Kapcsolathiba" #: editor/export_template_manager.cpp msgid "SSL Handshake Error" -msgstr "" +msgstr "SSL-Kézfogás Hiba" #: editor/export_template_manager.cpp msgid "Current Version:" -msgstr "" +msgstr "Jelenlegi Verzió:" #: editor/export_template_manager.cpp msgid "Installed Versions:" -msgstr "" +msgstr "TelepÃtett Verziók:" #: editor/export_template_manager.cpp msgid "Install From File" -msgstr "" +msgstr "TelepÃtés Fájlból" #: editor/export_template_manager.cpp msgid "Remove Template" -msgstr "" +msgstr "Sablon EltávolÃtása" #: editor/export_template_manager.cpp msgid "Select template file" -msgstr "" +msgstr "Válasszon sablonfájlt" #: editor/export_template_manager.cpp msgid "Export Template Manager" -msgstr "" +msgstr "Export Sablon KezelÅ‘" #: editor/export_template_manager.cpp msgid "Download Templates" -msgstr "" +msgstr "Sablonok Letöltése" #: editor/export_template_manager.cpp msgid "Select mirror from list: " -msgstr "" +msgstr "Válasszon tükröt a listából: " #: editor/file_type_cache.cpp msgid "Can't open file_type_cache.cch for writing, not saving file type cache!" msgstr "" +"Nem lehet megnyitni a file_type_cache.cch fájlt Ãrásra, a fájltÃpus " +"gyorsÃtótár nem lesz mentve!" #: editor/filesystem_dock.cpp msgid "Cannot navigate to '%s' as it has not been found in the file system!" -msgstr "" +msgstr "Nem lehet '%s'-t elérni, mivel nem létezik a fájlrendszerben!" #: editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails" -msgstr "" +msgstr "Elemek kirajzolása indexképek rácsába" #: editor/filesystem_dock.cpp msgid "View items as a list" -msgstr "" +msgstr "Elemek listázása" #: editor/filesystem_dock.cpp msgid "Status: Import of file failed. Please fix file and reimport manually." msgstr "" +"Ãllapot: Fájl importálása sikertelen. JavÃtsa a fájlt majd importálja be " +"újra manuálisan." #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." -msgstr "" +msgstr "Az erÅ‘források gyökere nem mozgatható vagy átnevezhetÅ‘." #: editor/filesystem_dock.cpp msgid "Cannot move a folder into itself." -msgstr "" +msgstr "Egy mappa nem helyezhetÅ‘ önmagába." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Error moving:" -msgstr "Hiba betöltéskor:" +msgstr "Hiba mozgatáskor:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Error duplicating:" -msgstr "Hiba betöltéskor:" +msgstr "Hiba másoláskor:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Unable to update dependencies:" -msgstr "A Scene-t nem sikerült betölteni a hiányzó függÅ‘ségek miatt:" +msgstr "Nem sikerült a függÅ‘ségek frissÃtése:" #: editor/filesystem_dock.cpp msgid "No name provided" -msgstr "" +msgstr "Nincs név megadva" #: editor/filesystem_dock.cpp msgid "Provided name contains invalid characters" -msgstr "" +msgstr "A megadott név érvénytelen karaktereket tartalmaz" #: editor/filesystem_dock.cpp msgid "No name provided." -msgstr "" +msgstr "Nincs név megadva." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." -msgstr "" +msgstr "A név érvénytelen karaktereket tartalmaz." #: editor/filesystem_dock.cpp msgid "A file or folder with this name already exists." -msgstr "" +msgstr "Egy fájl vagy mappa már létezik a megadott névvel." #: editor/filesystem_dock.cpp msgid "Renaming file:" -msgstr "" +msgstr "Fájl átnevezése:" #: editor/filesystem_dock.cpp msgid "Renaming folder:" -msgstr "" +msgstr "Mappa átnevezése:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Duplicating file:" -msgstr "Kiválasztás megkettÅ‘zése" +msgstr "Fájl másolása:" #: editor/filesystem_dock.cpp msgid "Duplicating folder:" -msgstr "" +msgstr "Mappa másolása:" #: editor/filesystem_dock.cpp msgid "Expand all" -msgstr "" +msgstr "Összes kibontása" #: editor/filesystem_dock.cpp msgid "Collapse all" -msgstr "" +msgstr "Összes összecsukása" #: editor/filesystem_dock.cpp msgid "Rename.." -msgstr "" +msgstr "Ãtnevezés.." #: editor/filesystem_dock.cpp msgid "Move To.." -msgstr "" +msgstr "Ãthelyezés.." #: editor/filesystem_dock.cpp msgid "Open Scene(s)" -msgstr "" +msgstr "Jelenet(ek) Megnyitása" #: editor/filesystem_dock.cpp msgid "Instance" -msgstr "" +msgstr "Példány" #: editor/filesystem_dock.cpp msgid "Edit Dependencies.." -msgstr "" +msgstr "FüggÅ‘ségek Szerkesztése.." #: editor/filesystem_dock.cpp msgid "View Owners.." -msgstr "" +msgstr "Tulajdonosok Megtekintése.." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Duplicate.." -msgstr "Animáció kulcs megkettÅ‘zése" +msgstr "MegkettÅ‘zés.." #: editor/filesystem_dock.cpp msgid "Previous Directory" -msgstr "" +msgstr "ElÅ‘zÅ‘ Könyvtár" #: editor/filesystem_dock.cpp msgid "Next Directory" -msgstr "" +msgstr "KövetkezÅ‘ Könyvtár" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" -msgstr "" +msgstr "Fájlrendszer Újra-vizsgálata" #: editor/filesystem_dock.cpp msgid "Toggle folder status as Favorite" -msgstr "" +msgstr "Mappa Kedvencnek jelölése / Kedvenc jelölés visszavonása" #: editor/filesystem_dock.cpp msgid "Instance the selected scene(s) as child of the selected node." msgstr "" +"Kiválasztott jelenet(ek) példányosÃtása a kiválasztott Node gyermekeként." #: editor/filesystem_dock.cpp msgid "" "Scanning Files,\n" "Please Wait.." msgstr "" +"Fájlok Vizsgálata,\n" +"Kérem Várjon.." #: editor/filesystem_dock.cpp msgid "Move" -msgstr "" +msgstr "Ãthelyezés" #: editor/filesystem_dock.cpp editor/plugins/animation_tree_editor_plugin.cpp #: editor/project_manager.cpp msgid "Rename" -msgstr "" +msgstr "Ãtnevezés" #: editor/groups_editor.cpp msgid "Add to Group" -msgstr "" +msgstr "Hozzáadás Csoporthoz" #: editor/groups_editor.cpp msgid "Remove from Group" -msgstr "" +msgstr "EltávolÃtás Csoportból" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" -msgstr "" +msgstr "Importálás Egyetlen Jelenetként" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Animations" -msgstr "" +msgstr "Importálás Külön Animációkkal" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials" -msgstr "" +msgstr "Importálás Külön Anyagokkal" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects" -msgstr "" +msgstr "Importálás Külön Objektumokkal" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials" -msgstr "" +msgstr "Importálás Külön Objektumokkal És Anyagokkal" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Animations" -msgstr "" +msgstr "Importálás Külön Objektumokkal És Animációkkal" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials+Animations" -msgstr "" +msgstr "Importálás Külön Anyagokkal És Animációkkal" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials+Animations" -msgstr "" +msgstr "Importálás Külön Objektumokkal, Anyagokkal És Animációkkal" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes" -msgstr "" +msgstr "Importálás Több Jelenetként" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes+Materials" -msgstr "" +msgstr "Importálás Több Jelentként és Anyagokként" #: editor/import/resource_importer_scene.cpp #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Import Scene" -msgstr "" +msgstr "Jelenet Importálása" #: editor/import/resource_importer_scene.cpp msgid "Importing Scene.." -msgstr "" +msgstr "Jelenet Importálása.." #: editor/import/resource_importer_scene.cpp msgid "Generating Lightmaps" -msgstr "" +msgstr "Fénytérképek Létrehozása" #: editor/import/resource_importer_scene.cpp msgid "Generating for Mesh: " -msgstr "" +msgstr "Létrehozás a KövetkezÅ‘ Hálóhoz: " #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script.." -msgstr "" +msgstr "TetszÅ‘leges Szkript Futtatása.." #: editor/import/resource_importer_scene.cpp msgid "Couldn't load post-import script:" -msgstr "" +msgstr "Nem sikerült az import utáni szkript betöltése:" #: editor/import/resource_importer_scene.cpp msgid "Invalid/broken script for post-import (check console):" msgstr "" +"Érvénytelen vagy sérült az importálás utáni szkript (ellenÅ‘rizze a konzolt):" #: editor/import/resource_importer_scene.cpp msgid "Error running post-import script:" -msgstr "" +msgstr "Hiba történt az importálás utána szkript futtatásakor:" #: editor/import/resource_importer_scene.cpp msgid "Saving.." -msgstr "" +msgstr "Mentés.." #: editor/import_dock.cpp msgid "Set as Default for '%s'" -msgstr "" +msgstr "BeállÃtás Alapértelmezettként '%s'-hez" #: editor/import_dock.cpp msgid "Clear Default for '%s'" -msgstr "" +msgstr "Alapértelmezett Törlése '%s'-nél" #: editor/import_dock.cpp msgid " Files" -msgstr "" +msgstr " Fájlok" #: editor/import_dock.cpp msgid "Import As:" -msgstr "" +msgstr "Importálás Mint:" #: editor/import_dock.cpp editor/property_editor.cpp msgid "Preset.." -msgstr "" +msgstr "BeépÃtett BeállÃtások.." #: editor/import_dock.cpp msgid "Reimport" -msgstr "" +msgstr "Újraimportálás" #: editor/multi_node_edit.cpp msgid "MultiNode Set" -msgstr "" +msgstr "MultiNode BeállÃtás" #: editor/node_dock.cpp msgid "Groups" -msgstr "" +msgstr "Csoportok" #: editor/node_dock.cpp msgid "Select a Node to edit Signals and Groups." -msgstr "" +msgstr "Válasszon ki egy Node-ot a Jelzések és Csoportok módosÃtásához." #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create Poly" -msgstr "" +msgstr "Sokszög Létrehozása" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/collision_polygon_editor_plugin.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Edit Poly" -msgstr "" +msgstr "Sokszög Szerkesztése" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Insert Point" -msgstr "" +msgstr "Pont Beszúrása" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/collision_polygon_editor_plugin.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Edit Poly (Remove Point)" -msgstr "" +msgstr "Sokszög Szerkesztése (Pont EltávolÃtása)" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Remove Poly And Point" -msgstr "" +msgstr "Sokszög és Pont EltávolÃtása" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Create a new polygon from scratch" -msgstr "" +msgstr "Új sokszög létrehozása a semmibÅ‘l" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "" @@ -2920,69 +2913,73 @@ msgid "" "Ctrl+LMB: Split Segment.\n" "RMB: Erase Point." msgstr "" +"MeglévÅ‘ sokszög módosÃtása:\n" +"Bal Egérgomb: Pont Mozgatása.\n" +"Ctrl + Bal Egérgomb: Szakasz Felosztása.\n" +"Jobb Egérgomb: Pont Eltörlése." #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Delete points" -msgstr "" +msgstr "Pontok Törlése" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" -msgstr "" +msgstr "Automatikus Lejátszás Váltása" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Animation Name:" -msgstr "" +msgstr "Új Animáció Neve:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Anim" -msgstr "" +msgstr "Új Animáció" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Animation Name:" -msgstr "" +msgstr "Animáció Nevének Megváltoztatása:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Delete Animation?" -msgstr "" +msgstr "Animáció Törlése?" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Remove Animation" -msgstr "" +msgstr "Animáció EltávolÃtása" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: Invalid animation name!" -msgstr "" +msgstr "HIBA: Érvénytelen animáció név!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: Animation name already exists!" -msgstr "" +msgstr "HIBA: Animáció név már létezik!" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Rename Animation" -msgstr "" +msgstr "Animáció Ãtnevezése" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Animation" -msgstr "" +msgstr "Animáció Hozzáadása" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Next Changed" -msgstr "" +msgstr "KövetkezÅ‘ Megváltozott Keverése" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Blend Time" -msgstr "" +msgstr "Keverési IdÅ‘ MódosÃtása" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load Animation" -msgstr "" +msgstr "Animáció Betöltése" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Duplicate Animation" -msgstr "" +msgstr "Animáció MegkettÅ‘zése" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: No animation to copy!" @@ -2990,91 +2987,92 @@ msgstr "HIBA: Nincs másolható animáció!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: No animation resource on clipboard!" -msgstr "" +msgstr "HIBA: Nincs animációs erÅ‘forrás a vágólapon!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pasted Animation" -msgstr "" +msgstr "Animáció Beillesztve" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Paste Animation" -msgstr "" +msgstr "Animáció Beillesztése" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: No animation to edit!" -msgstr "" +msgstr "HIBA: Nincs animáció szerkesztésre!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from current pos. (A)" msgstr "" +"A kiválasztott animáció lejátszása visszafelé a jelenlegi pozÃcióból. (A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from end. (Shift+A)" -msgstr "" +msgstr "A kiválasztott animáció lejátszása visszafelé a végétÅ‘l. (Shift + A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Stop animation playback. (S)" -msgstr "" +msgstr "Animáció lejátszásának leállÃtása. (S)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from start. (Shift+D)" -msgstr "" +msgstr "A kiválasztott animáció lejátszása az elejétÅ‘l. (Shift + D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" -msgstr "" +msgstr "A kiválasztott animáció lejátszása az jelenlegi pozÃcióból. (D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." -msgstr "" +msgstr "Animáció pozÃció (másodpercekben)." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Scale animation playback globally for the node." -msgstr "" +msgstr "Animáció lejátszás skálázása globálisan a Node-nak." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create new animation in player." -msgstr "" +msgstr "Új animáció létrehozása a lejátszóban." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load animation from disk." -msgstr "" +msgstr "Animáció betöltése a lemezrÅ‘l." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load an animation from disk." -msgstr "" +msgstr "Animáció betöltése a lemezrÅ‘l." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Save the current animation" -msgstr "" +msgstr "Jelenlegi animáció elmentése" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." -msgstr "" +msgstr "A lejátszóban lévÅ‘ animációk listájának megjelenÃtése." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Autoplay on Load" -msgstr "" +msgstr "Lejátszás Betöltéskor" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Target Blend Times" -msgstr "" +msgstr "Cél Keverési IdÅ‘k MódosÃtása" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Tools" -msgstr "" +msgstr "Animációs Eszközök" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Copy Animation" -msgstr "Animáció másolása" +msgstr "Animáció Másolása" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Onion Skinning" -msgstr "" +msgstr "MásolópapÃr Animáció (Onion Skinning)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Enable Onion Skinning" -msgstr "" +msgstr "MásolópapÃr Mód Bekapcsolása" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -3082,361 +3080,362 @@ msgstr "Irányok" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Past" -msgstr "" +msgstr "Múlt" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Future" -msgstr "" +msgstr "JövÅ‘" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Depth" -msgstr "" +msgstr "Mélység" #: editor/plugins/animation_player_editor_plugin.cpp msgid "1 step" -msgstr "" +msgstr "1 lépés" #: editor/plugins/animation_player_editor_plugin.cpp msgid "2 steps" -msgstr "" +msgstr "2 lépés" #: editor/plugins/animation_player_editor_plugin.cpp msgid "3 steps" -msgstr "" +msgstr "3 lépés" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Differences Only" -msgstr "" +msgstr "Csak A Különbségek" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Force White Modulate" -msgstr "" +msgstr "Fehérmoduláció KierÅ‘ltetése" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Include Gizmos (3D)" -msgstr "" +msgstr "Kihatás Gizmókra Is (3D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" -msgstr "" +msgstr "Új Animáció Létrehozása" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Name:" -msgstr "" +msgstr "Animáció Neve:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp #: editor/script_create_dialog.cpp msgid "Error!" -msgstr "" +msgstr "Hiba!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Times:" -msgstr "" +msgstr "Keverési IdÅ‘k:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Next (Auto Queue):" -msgstr "" +msgstr "KövetkezÅ‘ (Auto Sor):" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Cross-Animation Blend Times" -msgstr "" +msgstr "Animációk Közötti Keverési IdÅ‘k" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Animation" -msgstr "" +msgstr "Animáció" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "New name:" -msgstr "" +msgstr "Új név:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Edit Filters" -msgstr "" +msgstr "SzűrÅ‘k Szerkesztése" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp msgid "Scale:" -msgstr "" +msgstr "Skála:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Fade In (s):" -msgstr "" +msgstr "ElÅ‘tűnés (mp):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Fade Out (s):" -msgstr "" +msgstr "Elhalványulás (mp):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend" -msgstr "" +msgstr "Keverés" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Mix" -msgstr "" +msgstr "Mixelés" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Auto Restart:" -msgstr "" +msgstr "Automatikus ÚjraindÃtás:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Restart (s):" -msgstr "" +msgstr "ÚjraindÃtás (mp):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Random Restart (s):" -msgstr "" +msgstr "Véletlenszerű ÚjraindÃtás (mp):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Start!" -msgstr "" +msgstr "Start!" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp msgid "Amount:" -msgstr "" +msgstr "Mennyiség:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend:" -msgstr "" +msgstr "Keverés:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend 0:" -msgstr "" +msgstr "Keverés 0:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend 1:" -msgstr "" +msgstr "Keverés 1:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "X-Fade Time (s):" -msgstr "" +msgstr "Ãttűnési IdÅ‘ (mp):" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Current:" -msgstr "" +msgstr "Jelenlegi:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Add Input" -msgstr "" +msgstr "Bemenet Hozzáadása" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Clear Auto-Advance" -msgstr "" +msgstr "Automatikus Léptetés TisztÃtása" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Set Auto-Advance" -msgstr "" +msgstr "Automatikus Léptetés BeállÃtása" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Delete Input" -msgstr "" +msgstr "Bemenet Törlése" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Animation tree is valid." -msgstr "" +msgstr "Az animációs fa érvényes." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Animation tree is invalid." -msgstr "" +msgstr "Az animációs fa érvénytelen." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Animation Node" -msgstr "" +msgstr "Animációs Node" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "OneShot Node" -msgstr "" +msgstr "Egyszeri Node" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Mix Node" -msgstr "" +msgstr "MixelÅ‘ Node" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend2 Node" -msgstr "" +msgstr "Keverés2 Node" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend3 Node" -msgstr "" +msgstr "Keverés3 Node" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend4 Node" -msgstr "" +msgstr "Keverés4 Node" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeScale Node" -msgstr "" +msgstr "IdÅ‘Skála Node" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeSeek Node" -msgstr "" +msgstr "IdÅ‘KeresÅ‘ Node" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Transition Node" -msgstr "" +msgstr "Ãtmenet Node" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Import Animations.." -msgstr "" +msgstr "Animációk Importálása.." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Edit Node Filters" -msgstr "" +msgstr "Node SzűrÅ‘k MódosÃtása" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Filters.." -msgstr "" +msgstr "SzűrÅ‘k.." #: editor/plugins/animation_tree_editor_plugin.cpp -#, fuzzy msgid "AnimationTree" -msgstr "Animáció másolása" +msgstr "AnimationTree" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Free" -msgstr "" +msgstr "Ingyenes" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Contents:" -msgstr "" +msgstr "Tartalom:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "View Files" -msgstr "" +msgstr "Fájlok Megtekintése" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve hostname:" -msgstr "" +msgstr "A gazdagép neve nem oldható meg:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connection error, please try again." -msgstr "" +msgstr "Kapcsolat hiba, kérjük próbálja meg újra." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't connect to host:" -msgstr "" +msgstr "Nem lehet csatlakozni a kiszolgálóhoz:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "No response from host:" -msgstr "" +msgstr "Nincs válasz a kiszolgálótól:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, return code:" -msgstr "" +msgstr "Kérés sikertelen, visszatérési kód:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, too many redirects" -msgstr "" +msgstr "Kérés sikertelen, túl sok átirányÃtás" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Bad download hash, assuming file has been tampered with." msgstr "" +"Rossz letöltési hash, a program feltételezi, hogy a fájlt rosszindulatilag " +"módosÃtották." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Expected:" -msgstr "" +msgstr "Várt:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Got:" -msgstr "" +msgstr "Kapott:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed sha256 hash check" -msgstr "" +msgstr "sha256 hash ellenÅ‘rzés megbukott" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Asset Download Error:" -msgstr "" +msgstr "Eszköz Letöltési Hiba:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Fetching:" -msgstr "" +msgstr "Lekérés:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Resolving.." -msgstr "" +msgstr "Megoldás.." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Error making request" -msgstr "" +msgstr "Hiba kéréskor" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Idle" -msgstr "" +msgstr "Tétlen" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Retry" -msgstr "" +msgstr "Újra" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download Error" -msgstr "" +msgstr "Letöltési Hiba" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download for this asset is already in progress!" -msgstr "" +msgstr "Ennek az eszköznek a letöltése már folyamatban van!" #: editor/plugins/asset_library_editor_plugin.cpp msgid "first" -msgstr "" +msgstr "elsÅ‘" #: editor/plugins/asset_library_editor_plugin.cpp msgid "prev" -msgstr "" +msgstr "elÅ‘zÅ‘" #: editor/plugins/asset_library_editor_plugin.cpp msgid "next" -msgstr "" +msgstr "következÅ‘" #: editor/plugins/asset_library_editor_plugin.cpp msgid "last" -msgstr "" +msgstr "utolsó" #: editor/plugins/asset_library_editor_plugin.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "All" -msgstr "" +msgstr "Mind" #: editor/plugins/asset_library_editor_plugin.cpp #: editor/project_settings_editor.cpp msgid "Plugins" -msgstr "" +msgstr "BÅ‘vÃtmények" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Sort:" -msgstr "" +msgstr "Rendezés:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Reverse" -msgstr "" +msgstr "Visszafele" #: editor/plugins/asset_library_editor_plugin.cpp #: editor/project_settings_editor.cpp msgid "Category:" -msgstr "" +msgstr "Kategória:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Site:" -msgstr "" +msgstr "Oldal:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Support.." -msgstr "" +msgstr "Támogatás.." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Official" -msgstr "" +msgstr "Hivatalos" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Testing" -msgstr "" +msgstr "Tesztelés Alatt" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" -msgstr "" +msgstr "Eszköz ZIP Fájl" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -3444,135 +3443,146 @@ msgid "" "Save your scene (for images to be saved in the same dir), or pick a save " "path from the BakedLightmap properties." msgstr "" +"Nem lehet megállapÃtani mentési útvonalat a fénytérképeknek.\n" +"Mentse el a jelenetét (hogy aztán a képek ugyanabba a mappába legyenek " +"mentve), vagy válasszon egy mentési útvonalat a BakedLightmap " +"tulajdonságaiból." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" "No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake " "Light' flag is on." msgstr "" +"Nincs mesh, amibe adatokat süthetne. Bizonyosodjon meg arról, hogy " +"tartalmaznak egy UV2 csatornát, és hogy a 'Fény Besütése' opció be van " +"kapcsolva." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Failed creating lightmap images, make sure path is writable." msgstr "" +"Fénytérképek létrehozása sikertelen, gyÅ‘zÅ‘djön meg arról, hogy az útvonal " +"Ãrható." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Bake Lightmaps" -msgstr "" +msgstr "Fény Besütése" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" -msgstr "" +msgstr "ElÅ‘nézet" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap" -msgstr "" +msgstr "Illesztés BeállÃtása" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid Offset:" -msgstr "" +msgstr "Rács Eltolás:" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid Step:" -msgstr "" +msgstr "Rács Léptetés:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Offset:" -msgstr "" +msgstr "Forgatási Eltolás:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Step:" -msgstr "" +msgstr "Forgatási Léptetés:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move Pivot" -msgstr "" +msgstr "Forgatási Pont Mozgatása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move Action" -msgstr "" +msgstr "Mozgási Művelet" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move vertical guide" -msgstr "" +msgstr "FüggÅ‘leges vezetÅ‘vonal mozgatása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Create new vertical guide" -msgstr "" +msgstr "Új függÅ‘leges vezetÅ‘vonal létrehozása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Remove vertical guide" -msgstr "" +msgstr "FüggÅ‘leges vezetÅ‘vonal eltávolÃtása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move horizontal guide" -msgstr "" +msgstr "VÃzszintes vezetÅ‘vonal mozgatása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Create new horizontal guide" -msgstr "" +msgstr "Új vÃzszintes vezetÅ‘vonal létrehozása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Remove horizontal guide" -msgstr "" +msgstr "VÃzszintes vezetÅ‘vonal eltávolÃtása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Create new horizontal and vertical guides" -msgstr "" +msgstr "Új vÃzszintes és függÅ‘leges vezetÅ‘vonalak létrehozása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Edit IK Chain" -msgstr "" +msgstr "IK Lánc Szerkesztése" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Edit CanvasItem" -msgstr "" +msgstr "CanvasItem Szerkesztése" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" -msgstr "" +msgstr "Csak Horgonyok" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Change Anchors and Margins" -msgstr "" +msgstr "Horgonyok és Margók MódosÃtása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Change Anchors" -msgstr "" +msgstr "Horgonyok MódosÃtása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" -msgstr "" +msgstr "Póz Beillesztése" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Select Mode" -msgstr "" +msgstr "Kiválasztó Mód" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Drag: Rotate" -msgstr "" +msgstr "Húzás: Forgatás" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+Drag: Move" -msgstr "" +msgstr "Alt + Húzás: Mozgatás" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." msgstr "" +"Nyomja meg a 'v' gombot a Forgatási Pont Megváltoztatásához, Vagy 'Shift + " +"v'-t a Forgatási Pont Húzásához (mozgás közben)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+RMB: Depth list selection" -msgstr "" +msgstr "Alt + Jobb Egérgomb: Mélységi lista választás" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move Mode" -msgstr "" +msgstr "Mozgás Mód" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotate Mode" -msgstr "" +msgstr "Forgató mód" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -3580,895 +3590,903 @@ msgid "" "Show a list of all objects at the position clicked\n" "(same as Alt+RMB in select mode)." msgstr "" +"Lista mutatási minden objektumról a kattintás helye alatt\n" +"(ugyanaz, mint Alt + Jobb Egérgomb Kiválasztó Módban)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Click to change object's rotation pivot." -msgstr "" +msgstr "Kattintson ide az objektum forgatási pontjának megváltoztatásához." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Pan Mode" -msgstr "" +msgstr "Pásztázás Mód" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Toggles snapping" -msgstr "" +msgstr "Illesztés be- és kikapcsolása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Snap" -msgstr "" +msgstr "Illesztés Használata" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snapping options" -msgstr "" +msgstr "Illesztési beállÃtások" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to grid" -msgstr "" +msgstr "Rácshoz illesztés" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Rotation Snap" -msgstr "" +msgstr "Forgatási Illesztés Használata" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap..." -msgstr "" +msgstr "Illesztés BeállÃtása..." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap Relative" -msgstr "" +msgstr "RelatÃv Illesztés" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Pixel Snap" -msgstr "" +msgstr "Pixelhez Illesztés" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Smart snapping" -msgstr "" +msgstr "Intelligens illesztés" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to parent" -msgstr "" +msgstr "Illesztés szülÅ‘höz" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to node anchor" -msgstr "" +msgstr "Illesztés node horgonyhoz" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to node sides" -msgstr "" +msgstr "Illesztés node oldalakhoz" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to other nodes" -msgstr "" +msgstr "Illesztés más node-okhoz" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to guides" -msgstr "" +msgstr "Illesztés vezetÅ‘vonalakhoz" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock the selected object in place (can't be moved)." -msgstr "" +msgstr "A kiválasztott objektum zárolása (mozgathatatlanná tétele)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Unlock the selected object (can be moved)." -msgstr "" +msgstr "A kiválasztott objektum feloldása (mozgathatóvá tétele)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Makes sure the object's children are not selectable." -msgstr "" +msgstr "Kiválaszthatatlanná teszi az objektum gyermekeit." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Restores the object's children's ability to be selected." -msgstr "" +msgstr "Újra kiválaszthatóvá teszi az objektum gyermekeit." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make Bones" -msgstr "" +msgstr "Csontok Létrehozása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Bones" -msgstr "" +msgstr "Csontok Törlése" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Bones" -msgstr "" +msgstr "Csontok Mutatása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" -msgstr "" +msgstr "IK Lánc Létrehozása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear IK Chain" -msgstr "" +msgstr "IK Lánc Törlése" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "View" -msgstr "" +msgstr "Nézet" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Show Grid" -msgstr "" +msgstr "Rács MegjelenÃtése" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" -msgstr "" +msgid "Show Helpers" +msgstr "SegÃtÅ‘k MegjelenÃtése" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" -msgstr "" +msgid "Show Rulers" +msgstr "Vonalzók MegjelenÃtése" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" -msgstr "" +msgid "Show Guides" +msgstr "VezetÅ‘vonalak MegjelenÃtése" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Selection" -msgstr "" +msgstr "Kijelölés Középre" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Frame Selection" -msgstr "" +msgstr "Kijelölés Keretezése" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" -msgstr "" +msgstr "Elrendezés" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Keys" -msgstr "" +msgstr "Kulcsok Beszúrása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key" -msgstr "" +msgstr "Kulcs Beszúrása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key (Existing Tracks)" -msgstr "" +msgstr "Kulcs Beszúrása (MeglévÅ‘ Nyomvonalakra)" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Copy Pose" -msgstr "Póz másolása" +msgstr "Póz Másolása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Pose" -msgstr "" +msgstr "Póz Törlése" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Drag pivot from mouse position" -msgstr "" +msgstr "Forgatási pont húzása az egér helyétÅ‘l" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Set pivot at mouse position" -msgstr "" +msgstr "Forgatási pont beállÃtása az egér helyére" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Multiply grid step by 2" -msgstr "" +msgstr "Rács Léptetés Mértékének Kétszerezése" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Divide grid step by 2" -msgstr "" +msgstr "Rács Léptetés Mértékének Felezése" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" -msgstr "" +msgstr "%s Hozzáadása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Adding %s..." -msgstr "" +msgstr "%s Hozzáadása..." #: editor/plugins/canvas_item_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Ok" -msgstr "" +msgstr "Rendben" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Cannot instantiate multiple nodes without root." -msgstr "" +msgstr "Nem lehet több node-ot példányosÃtani gyökér nélkül." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Create Node" -msgstr "" +msgstr "Node Létrehozása" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Error instancing scene from %s" -msgstr "" +msgstr "Hiba történt a jelenet példányosÃtáskor %s-bÅ‘l" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Change default type" -msgstr "" +msgstr "Alapértelmezett tÃpus megváltoztatása" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" "Drag & drop + Shift : Add node as sibling\n" "Drag & drop + Alt : Change node type" msgstr "" +"Fogd és vidd + Shift: Node hozzáadása testvérként\n" +"Fogd és vidd + Alt: Node tÃpusának megváltoztatása" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Create Poly3D" -msgstr "" +msgstr "Poly3D Létrehozása" #: editor/plugins/collision_shape_2d_editor_plugin.cpp msgid "Set Handle" -msgstr "" +msgstr "Fogantyú BeállÃtása" #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Remove item %d?" -msgstr "" +msgstr "%d elem eltávolÃtása?" #: editor/plugins/cube_grid_theme_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp msgid "Add Item" -msgstr "" +msgstr "Elem Hozzáadása" #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Remove Selected Item" -msgstr "" +msgstr "Kijelölt Elem EltávolÃtása" #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Import from Scene" -msgstr "" +msgstr "Importálás JelenetbÅ‘l" #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Update from Scene" -msgstr "" +msgstr "FrissÃtés JelenetbÅ‘l" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat0" -msgstr "" +msgstr "Lapos 0" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat1" -msgstr "" +msgstr "Lapos 1" #: editor/plugins/curve_editor_plugin.cpp msgid "Ease in" -msgstr "" +msgstr "Lassan Be" #: editor/plugins/curve_editor_plugin.cpp msgid "Ease out" -msgstr "" +msgstr "Lassan Ki" #: editor/plugins/curve_editor_plugin.cpp msgid "Smoothstep" -msgstr "" +msgstr "SimÃtott Lépés" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Point" -msgstr "" +msgstr "Görbe Pontjának MódosÃtása" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Tangent" -msgstr "" +msgstr "Görbe ÉrintÅ‘jének MódosÃtása" #: editor/plugins/curve_editor_plugin.cpp msgid "Load Curve Preset" -msgstr "" +msgstr "ElÅ‘re BeállÃtott Görbe Betöltése" #: editor/plugins/curve_editor_plugin.cpp msgid "Add point" -msgstr "" +msgstr "Pont hozzáadása" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove point" -msgstr "" +msgstr "Pont eltávolÃtása" #: editor/plugins/curve_editor_plugin.cpp msgid "Left linear" -msgstr "" +msgstr "Bal lineáris" #: editor/plugins/curve_editor_plugin.cpp msgid "Right linear" -msgstr "" +msgstr "Jobb lineáris" #: editor/plugins/curve_editor_plugin.cpp msgid "Load preset" -msgstr "" +msgstr "ElÅ‘re beállÃtott betöltése" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove Curve Point" -msgstr "" +msgstr "Görbe Pontjának EltávolÃtása" #: editor/plugins/curve_editor_plugin.cpp msgid "Toggle Curve Linear Tangent" -msgstr "" +msgstr "Görbe Lineáris ÉrintÅ‘jének Kapcsolása" #: editor/plugins/curve_editor_plugin.cpp msgid "Hold Shift to edit tangents individually" -msgstr "" +msgstr "Tartsa lenyomva a Shift gombot az érintÅ‘k egyenkénti szerkesztéséhez" #: editor/plugins/gi_probe_editor_plugin.cpp msgid "Bake GI Probe" -msgstr "" +msgstr "GI Szonda Besütése" #: editor/plugins/gradient_editor_plugin.cpp msgid "Add/Remove Color Ramp Point" -msgstr "" +msgstr "SzÃn Gradiens Pont Hozzáadása / EltávolÃtása" #: editor/plugins/gradient_editor_plugin.cpp #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Modify Color Ramp" -msgstr "" +msgstr "SzÃn Gradiens MódosÃtása" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" -msgstr "" +msgstr "%d elem" #: editor/plugins/item_list_editor_plugin.cpp msgid "Items" -msgstr "" +msgstr "Elemek" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item List Editor" -msgstr "" +msgstr "Elemlista SzerkesztÅ‘" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "" "No OccluderPolygon2D resource on this node.\n" "Create and assign one?" msgstr "" +"Nincs OccluderPolygon2D erÅ‘forrás ezen a node-on.\n" +"Létrehoz egyet és hozzárendeli a node-hoz?" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create Occluder Polygon" -msgstr "" +msgstr "Ãrnyékoló Sokszög Létrehozása" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create a new polygon from scratch." -msgstr "" +msgstr "Új sokszög létrehozása a semmibÅ‘l." #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Edit existing polygon:" -msgstr "" +msgstr "LétezÅ‘ sokszög szerkesztése:" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "LMB: Move Point." -msgstr "" +msgstr "Bal Egérgomb: Pont Mozgatása." #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Ctrl+LMB: Split Segment." -msgstr "" +msgstr "Ctrl + Bal Egérgomb: Szakasz Felosztása." #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "RMB: Erase Point." -msgstr "" +msgstr "Jobb Egérgomb: Pont Törlése." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh is empty!" -msgstr "" +msgstr "A háló üres!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" -msgstr "" +msgstr "Statikus Trimesh Test Létrehozása" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Convex Body" -msgstr "" +msgstr "Statikus Konvex Test Létrehozása" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "This doesn't work on scene root!" -msgstr "" +msgstr "Ez nem hajtható végre a jelenet gyökerén!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Shape" -msgstr "" +msgstr "Trimesh Alakzat Létrehozása" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Convex Shape" -msgstr "" +msgstr "Konvex Alakzat Létrehozása" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" -msgstr "" +msgstr "Navigációs Háló Létrehozása" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Contained Mesh is not of type ArrayMesh." -msgstr "" +msgstr "A tartalmazott Mesh nem ArrayMesh tÃpusú." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Unwrap failed, mesh may not be manifold?" -msgstr "" +msgstr "UV kibontás sikertelen, a mesh talán nem sokrétű?" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "No mesh to debug." -msgstr "" +msgstr "Nincs mesh a hibakereséshez." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Model has no UV in this layer" -msgstr "" +msgstr "A modellnek nincs UV-je ezen a rétegen" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "MeshInstance lacks a Mesh!" -msgstr "" +msgstr "MeshInstance-nak nincs Mesh-e!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh has not surface to create outlines from!" msgstr "" +"A Mesh-nek nincsenek felszÃnei, ami alapján körvonalakat lehetni készÃteni!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Could not create outline!" -msgstr "" +msgstr "KörvonalkészÃtés sikertelen!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline" -msgstr "" +msgstr "Körvonal KészÃtése" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh" -msgstr "" +msgstr "Mesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Body" -msgstr "" +msgstr "Trimesh Statikus Test Létrehozása" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Convex Static Body" -msgstr "" +msgstr "Konvex Statikus Test Létrehozása" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Collision Sibling" -msgstr "" +msgstr "Trimesh Ãœtközési Testvér Létrehozása" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Convex Collision Sibling" -msgstr "" +msgstr "Konvex Ãœtközési Testvér Létrehozása" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh.." -msgstr "" +msgstr "Körvonalháló Létrehozása.." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "View UV1" -msgstr "" +msgstr "UV1 Megtekintése" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "View UV2" -msgstr "" +msgstr "UV2 Megtekintése" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Unwrap UV2 for Lightmap/AO" -msgstr "" +msgstr "UV2 Kicsomagolása Fénytérképhez / AO-hoz" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh" -msgstr "" +msgstr "Körvonalháló KészÃtése" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Outline Size:" -msgstr "" +msgstr "Körvonal Mérete:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." msgstr "" +"Nincs háló forrás meghatározva (és nincs MultiMesh a Node-ban beállÃtva)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and MultiMesh contains no Mesh)." -msgstr "" +msgstr "Nincs háló forrás meghatározva (és a MultiMesh nem tartalmaz Mesh-t)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (invalid path)." -msgstr "" +msgstr "Mesh forrás érvénytelen (érvénytelen útvonal)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (not a MeshInstance)." -msgstr "" +msgstr "Mesh forrás érvénytelen (nem MeshInstance)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (contains no Mesh resource)." -msgstr "" +msgstr "Mesh forrás érvénytelen (nem tartalmaz Mesh erÅ‘forrást)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No surface source specified." -msgstr "" +msgstr "Nincs felületi forrás meghatározva." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (invalid path)." -msgstr "" +msgstr "Felületi forrás érvénytelen (érvénytelen útvonal)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (no geometry)." -msgstr "" +msgstr "Felületi forrás érvénytelen (nincs geometria)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (no faces)." -msgstr "" +msgstr "Felületi forrás érvénytelen (nincsenek oldalak)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Parent has no solid faces to populate." -msgstr "" +msgstr "A szülÅ‘nek nincsenek kitölthetÅ‘ szilárd oldalai." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Couldn't map area." -msgstr "" +msgstr "A területet nem lehetett leképezni." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Source Mesh:" -msgstr "" +msgstr "Válasszon Ki Egy Forrás Mesh-t:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Select a Target Surface:" -msgstr "" +msgstr "Válasszon Ki Egy Cél Felületet:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Populate Surface" -msgstr "" +msgstr "Felület Kitöltése" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Populate MultiMesh" -msgstr "" +msgstr "MultiMesh Kitöltése" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Target Surface:" -msgstr "" +msgstr "Cél Felület:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Source Mesh:" -msgstr "" +msgstr "Forrás Mesh:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "X-Axis" -msgstr "" +msgstr "X-Tengely" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Y-Axis" -msgstr "" +msgstr "Y-Tengely" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Z-Axis" -msgstr "" +msgstr "Z-Tengely" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh Up Axis:" -msgstr "" +msgstr "Mesh \"Fel\" Tengelye:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Random Rotation:" -msgstr "" +msgstr "Véletlenszerű Forgatás:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Random Tilt:" -msgstr "" +msgstr "Véletlenszerű Billentés:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Random Scale:" -msgstr "" +msgstr "Véletlenszerű Skálázás:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Populate" -msgstr "" +msgstr "Kitöltés" #: editor/plugins/navigation_mesh_editor_plugin.cpp msgid "Bake!" -msgstr "" +msgstr "Besütés!" #: editor/plugins/navigation_mesh_editor_plugin.cpp msgid "Bake the navigation mesh." -msgstr "" +msgstr "A navigációs mesh besütése." #: editor/plugins/navigation_mesh_editor_plugin.cpp msgid "Clear the navigation mesh." -msgstr "" +msgstr "Navigációs háló törlése." #: editor/plugins/navigation_mesh_generator.cpp msgid "Setting up Configuration..." -msgstr "" +msgstr "Konfiguráció beállÃtása…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Calculating grid size..." -msgstr "" +msgstr "Rácsméret kiszámÃtása…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Creating heightfield..." -msgstr "" +msgstr "MagasságmezÅ‘ létrehozása…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Marking walkable triangles..." -msgstr "" +msgstr "Járható háromszögek megjelölése…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Constructing compact heightfield..." -msgstr "" +msgstr "Kompakt magasságmezÅ‘ kiépÃtése…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Eroding walkable area..." -msgstr "" +msgstr "Járható terület lepusztÃtása…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Partitioning..." -msgstr "" +msgstr "Particionálás…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Creating contours..." -msgstr "" +msgstr "Kontúrok létrehozása…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Creating polymesh..." -msgstr "" +msgstr "Polymesh létrehozása…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Converting to native navigation mesh..." -msgstr "" +msgstr "Ãtkonvertálás natÃv navigációs hálóra…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Navigation Mesh Generator Setup:" -msgstr "" +msgstr "Navigációs Háló Generátor BeállÃtás:" #: editor/plugins/navigation_mesh_generator.cpp msgid "Parsing Geometry..." -msgstr "" +msgstr "Geometria Elemzése…" #: editor/plugins/navigation_mesh_generator.cpp msgid "Done!" -msgstr "" +msgstr "Kész!" #: editor/plugins/navigation_polygon_editor_plugin.cpp msgid "Create Navigation Polygon" -msgstr "" +msgstr "Navigációs Sokszög Létrehozása" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generating AABB" -msgstr "" +msgstr "AABB Generálása" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Can only set point into a ParticlesMaterial process material" -msgstr "" +msgstr "Csak egy ParticlesMaterial feldolgozó anyagba állÃthat pontot" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Error loading image:" -msgstr "" +msgstr "Hiba a kép betöltésekor:" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "No pixels with transparency > 128 in image.." -msgstr "" +msgstr "Nem létezik egyetlen pixel sem >128-as átlátszósággal a képben.." #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generate Visibility Rect" -msgstr "" +msgstr "Láthatósági Téglalap Generálása" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Load Emission Mask" -msgstr "" +msgstr "Kibocsátási Maszk Betöltése" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" -msgstr "" +msgstr "Kibocsátási Maszk Törlése" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Particles" -msgstr "" +msgstr "Részecskék" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generated Point Count:" -msgstr "" +msgstr "Generált Pontok Száma:" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" -msgstr "" +msgstr "Generálási IdÅ‘ (mp):" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Emission Mask" -msgstr "" +msgstr "Kibocsátási Maszk" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Capture from Pixel" -msgstr "" +msgstr "Kinyerés PixelbÅ‘l" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Emission Colors" -msgstr "" +msgstr "Kibocsátási SzÃnek" #: editor/plugins/particles_editor_plugin.cpp msgid "Node does not contain geometry." -msgstr "" +msgstr "A Node nem tartalmaz geometriát." #: editor/plugins/particles_editor_plugin.cpp msgid "Node does not contain geometry (faces)." -msgstr "" +msgstr "A Node nem tartalmaz geometriát (oldalakat)." #: editor/plugins/particles_editor_plugin.cpp msgid "A processor material of type 'ParticlesMaterial' is required." -msgstr "" +msgstr "Egy 'ParticlesMaterial' tÃpusú feldolgozó anyag szükséges." #: editor/plugins/particles_editor_plugin.cpp msgid "Faces contain no area!" -msgstr "" +msgstr "Az oldalak nem tartalmaznak területet!" #: editor/plugins/particles_editor_plugin.cpp msgid "No faces!" -msgstr "" +msgstr "Nincsenek oldalak!" #: editor/plugins/particles_editor_plugin.cpp msgid "Generate AABB" -msgstr "" +msgstr "AABB Generálása" #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Mesh" -msgstr "" +msgstr "Kibocsátási Pontok Létrehozása A Mesh Alapján" #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Node" -msgstr "" +msgstr "Kibocsátási Pontok Létrehozása A Node Alapján" #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emitter" -msgstr "" +msgstr "Kibocsátó Létrehozása" #: editor/plugins/particles_editor_plugin.cpp msgid "Emission Points:" -msgstr "" +msgstr "Kibocsátási Pontok:" #: editor/plugins/particles_editor_plugin.cpp msgid "Surface Points" -msgstr "" +msgstr "Felületi Pontok" #: editor/plugins/particles_editor_plugin.cpp msgid "Surface Points+Normal (Directed)" -msgstr "" +msgstr "Felületi Pontok + Normálok (IrányÃtott)" #: editor/plugins/particles_editor_plugin.cpp msgid "Volume" -msgstr "" +msgstr "Mennyiség" #: editor/plugins/particles_editor_plugin.cpp msgid "Emission Source: " -msgstr "" +msgstr "Kibocsátási Forrás: " #: editor/plugins/particles_editor_plugin.cpp msgid "Generate Visibility AABB" -msgstr "" +msgstr "Láthatósági AABB Generálása" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" -msgstr "" +msgstr "Pont EltávolÃtása GörbérÅ‘l" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Out-Control from Curve" -msgstr "" +msgstr "Ki-VezérlÅ‘ EltávolÃtása GörbébÅ‘l" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove In-Control from Curve" -msgstr "" +msgstr "Be-VezérlÅ‘ EltávolÃtása GörbébÅ‘l" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Add Point to Curve" -msgstr "" +msgstr "Pont Hozzáadása a Görbéhez" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Move Point in Curve" -msgstr "" +msgstr "Pont Mozgatása a Görbén" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Move In-Control in Curve" -msgstr "" +msgstr "Be-VezérlÅ‘ Mozgatása a Görbén" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Move Out-Control in Curve" -msgstr "" +msgstr "Ki-VezérlÅ‘ Mozgatása a Görbén" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Select Points" -msgstr "" +msgstr "Pontok Kiválasztása" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Shift+Drag: Select Control Points" -msgstr "" +msgstr "Shift + Húzás: VezérlÅ‘pontok Kiválasztása" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Click: Add Point" -msgstr "" +msgstr "Kattintás: Pont Hozzáadása" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Right Click: Delete Point" -msgstr "" +msgstr "Jobb Kattintás: Pont Törlése" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Select Control Points (Shift+Drag)" -msgstr "" +msgstr "VezérlÅ‘pontok Kiválasztása (Shift + Húzás)" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Add Point (in empty space)" -msgstr "" +msgstr "Pont Hozzáadása (üres helyre)" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Split Segment (in curve)" -msgstr "" +msgstr "Szakasz Felosztása (görbén)" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Delete Point" -msgstr "" +msgstr "Pont Törlése" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Close Curve" -msgstr "" +msgstr "Görbe Lezárása" #: editor/plugins/path_editor_plugin.cpp msgid "Curve Point #" -msgstr "" +msgstr "Görbe Pont #" #: editor/plugins/path_editor_plugin.cpp msgid "Set Curve Point Position" -msgstr "" +msgstr "Görbe Pont PozÃció BeállÃtása" #: editor/plugins/path_editor_plugin.cpp msgid "Set Curve In Position" -msgstr "" +msgstr "Be-Görbe PozÃció BeállÃtása" #: editor/plugins/path_editor_plugin.cpp msgid "Set Curve Out Position" -msgstr "" +msgstr "Ki-Görbe PozÃció BeállÃtása" #: editor/plugins/path_editor_plugin.cpp msgid "Split Path" -msgstr "" +msgstr "Útvonal Felosztása" #: editor/plugins/path_editor_plugin.cpp msgid "Remove Path Point" -msgstr "" +msgstr "Útvonal Pont EltávolÃtása" #: editor/plugins/path_editor_plugin.cpp msgid "Remove Out-Control Point" -msgstr "" +msgstr "Ki-VezérlÅ‘ Pont EltávolÃtása" #: editor/plugins/path_editor_plugin.cpp msgid "Remove In-Control Point" -msgstr "" +msgstr "Be-VezérlÅ‘ Pont EltávolÃtása" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create UV Map" -msgstr "" +msgstr "UV Térkép Létrehozása" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Transform UV Map" -msgstr "" +msgstr "UV Térkép Transzformálása" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon 2D UV Editor" -msgstr "" +msgstr "2D UV Sokszög SzerkesztÅ‘" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Move Point" -msgstr "" +msgstr "Pont Mozgatása" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Ctrl: Rotate" -msgstr "" +msgstr "Ctrl: Forgatás" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift: Move All" -msgstr "" +msgstr "Shift: Mind Mozgatása" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift+Ctrl: Scale" -msgstr "" +msgstr "Shift + Ctrl: Skálázás" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Move Polygon" -msgstr "" +msgstr "Sokszög Mozgatása" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Rotate Polygon" -msgstr "" +msgstr "Sokszög Forgatása" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Scale Polygon" -msgstr "" +msgstr "Sokszög Skálázása" #: editor/plugins/polygon_2d_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -4476,309 +4494,328 @@ msgstr "" #: editor/project_settings_editor.cpp editor/property_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Edit" -msgstr "" +msgstr "Szerkesztés" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon->UV" -msgstr "" +msgstr "Sokszög -> UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "UV->Polygon" -msgstr "" +msgstr "UV -> Sokszög" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Clear UV" -msgstr "" +msgstr "UV Törlése" #: editor/plugins/polygon_2d_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap" -msgstr "" +msgstr "Illesztés" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Enable Snap" -msgstr "" +msgstr "Illesztés Engedélyezése" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid" -msgstr "" +msgstr "Rács" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "ERROR: Couldn't load resource!" -msgstr "" +msgstr "HIBA: Nem sikerült betölteni az erÅ‘forrást!" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Add Resource" -msgstr "" +msgstr "ErÅ‘forrás Hozzáadása" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Rename Resource" -msgstr "" +msgstr "ErÅ‘forrás Ãtnevezése" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Delete Resource" -msgstr "" +msgstr "ErÅ‘forrás Törlése" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Resource clipboard is empty!" -msgstr "" +msgstr "Az erÅ‘forrás vágólap üres!" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Megnyitás SzerkesztÅ‘ben" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Példány:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "TÃpus:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" -msgstr "" +msgstr "ErÅ‘forrás Betöltése" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" -msgstr "" +msgstr "Beillesztés" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "ResourcePreloader" -msgstr "" +msgstr "ResourcePreloader" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Files" -msgstr "" +msgstr "Legutóbbi Fájlok Törlése" #: editor/plugins/script_editor_plugin.cpp msgid "Close and save changes?" -msgstr "" +msgstr "Bezárja és menti a változásokat?" #: editor/plugins/script_editor_plugin.cpp msgid "Error while saving theme" -msgstr "" +msgstr "HIba történt a téma mentésekor" #: editor/plugins/script_editor_plugin.cpp msgid "Error saving" -msgstr "" +msgstr "Hiba mentés közben" #: editor/plugins/script_editor_plugin.cpp msgid "Error importing theme" -msgstr "" +msgstr "Hiba történt a téma importálásakor" #: editor/plugins/script_editor_plugin.cpp msgid "Error importing" -msgstr "" +msgstr "Hiba importáláskor" #: editor/plugins/script_editor_plugin.cpp msgid "Import Theme" -msgstr "" +msgstr "Téma Importálása" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme As.." -msgstr "" +msgstr "Téma Mentése Másként.." #: editor/plugins/script_editor_plugin.cpp msgid " Class Reference" -msgstr "" +msgstr " Osztály Referencia" #: editor/plugins/script_editor_plugin.cpp msgid "Sort" -msgstr "" +msgstr "Rendezés" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Move Up" -msgstr "" +msgstr "Mozgatás Felfelé" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Move Down" -msgstr "" +msgstr "Mozgatás Lefelé" #: editor/plugins/script_editor_plugin.cpp msgid "Next script" -msgstr "" +msgstr "KövetkezÅ‘ Szkript" #: editor/plugins/script_editor_plugin.cpp msgid "Previous script" -msgstr "" +msgstr "ElÅ‘zÅ‘ Szkript" #: editor/plugins/script_editor_plugin.cpp msgid "File" -msgstr "" +msgstr "Fájl" #: editor/plugins/script_editor_plugin.cpp msgid "New" -msgstr "" +msgstr "Új" #: editor/plugins/script_editor_plugin.cpp msgid "Save All" -msgstr "" +msgstr "Összes Mentése" #: editor/plugins/script_editor_plugin.cpp msgid "Soft Reload Script" -msgstr "" +msgstr "Szkript Puha Újratöltése" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Copy Script Path" -msgstr "Útvonal másolása" +msgstr "Szkript Útvonal Másolása" #: editor/plugins/script_editor_plugin.cpp msgid "Show In File System" -msgstr "" +msgstr "Mutassa a Fájlrendszerben" #: editor/plugins/script_editor_plugin.cpp msgid "History Prev" -msgstr "" +msgstr "ElÅ‘zÅ‘ ElÅ‘zmény" #: editor/plugins/script_editor_plugin.cpp msgid "History Next" -msgstr "" +msgstr "KövetkezÅ‘ ElÅ‘zmény" #: editor/plugins/script_editor_plugin.cpp msgid "Reload Theme" -msgstr "" +msgstr "Téma Újratöltése" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme" -msgstr "" +msgstr "Téma Mentése" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme As" -msgstr "" +msgstr "Téma Mentése Másként" #: editor/plugins/script_editor_plugin.cpp msgid "Close Docs" -msgstr "" +msgstr "Dokumentációs Lapok Bezárása" #: editor/plugins/script_editor_plugin.cpp msgid "Close All" -msgstr "" +msgstr "Mind Bezárása" #: editor/plugins/script_editor_plugin.cpp msgid "Close Other Tabs" -msgstr "" +msgstr "A Többi Lap Bezárása" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp msgid "Run" -msgstr "" +msgstr "Futtatás" #: editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" -msgstr "" +msgstr "Szkript Panel MegjelenÃtése" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find.." -msgstr "" +msgstr "Keresés.." #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find Next" -msgstr "" +msgstr "KövetkezÅ‘ Keresése" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Over" -msgstr "" +msgstr "Ãtlépés" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" -msgstr "" +msgstr "Belépés" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Break" -msgstr "" +msgstr "Szünet" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp #: editor/script_editor_debugger.cpp msgid "Continue" -msgstr "" +msgstr "Folytatás" #: editor/plugins/script_editor_plugin.cpp msgid "Keep Debugger Open" -msgstr "" +msgstr "HibakeresÅ‘ Nyitva Tartása" #: editor/plugins/script_editor_plugin.cpp msgid "Debug with external editor" -msgstr "" +msgstr "Hibakeresés külsÅ‘ szerkesztÅ‘vel" #: editor/plugins/script_editor_plugin.cpp msgid "Open Godot online documentation" -msgstr "" +msgstr "Godot online dokumentáció megnyitása" #: editor/plugins/script_editor_plugin.cpp msgid "Search the class hierarchy." -msgstr "" +msgstr "Keresés az osztályhierarchiában." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." -msgstr "" +msgstr "Keresés a referencia dokumentációban." #: editor/plugins/script_editor_plugin.cpp msgid "Go to previous edited document." -msgstr "" +msgstr "Ugrás az elÅ‘zÅ‘leg szerkesztett dokumentumra." #: editor/plugins/script_editor_plugin.cpp msgid "Go to next edited document." -msgstr "" +msgstr "Ugrás a következÅ‘leg szerkesztett dokumentumra." #: editor/plugins/script_editor_plugin.cpp msgid "Discard" -msgstr "" +msgstr "Elvetés" #: editor/plugins/script_editor_plugin.cpp msgid "Create Script" -msgstr "" +msgstr "Szkript Létrehozása" #: editor/plugins/script_editor_plugin.cpp msgid "" "The following files are newer on disk.\n" "What action should be taken?:" msgstr "" +"A alábbi fájlok újabbak a lemezen.\n" +"Mit szeretne lépni?:" #: editor/plugins/script_editor_plugin.cpp msgid "Reload" -msgstr "" +msgstr "Újratöltés" #: editor/plugins/script_editor_plugin.cpp msgid "Resave" -msgstr "" +msgstr "Újramentés" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" -msgstr "" +msgstr "HibakeresÅ‘" #: editor/plugins/script_editor_plugin.cpp msgid "" "Built-in scripts can only be edited when the scene they belong to is loaded" msgstr "" +"A beépÃtett szkriptek csak akkor szerkeszthetÅ‘ek, amikor az a jelenet, " +"amihez tartoznak, éppen be van töltve" #: editor/plugins/script_text_editor.cpp msgid "Only resources from filesystem can be dropped." -msgstr "" +msgstr "Csak a fájlrendszerbÅ‘l eredÅ‘ erÅ‘forrásokat lehet bedobni." #: editor/plugins/script_text_editor.cpp msgid "Pick Color" -msgstr "" +msgstr "SzÃn Választása" #: editor/plugins/script_text_editor.cpp msgid "Convert Case" -msgstr "" +msgstr "Kis- és Nagybetűk Konvertálása" #: editor/plugins/script_text_editor.cpp msgid "Uppercase" -msgstr "" +msgstr "Mind Nagybetű" #: editor/plugins/script_text_editor.cpp msgid "Lowercase" -msgstr "" +msgstr "Mind Kisbetű" #: editor/plugins/script_text_editor.cpp msgid "Capitalize" -msgstr "" +msgstr "Szó Eleji Nagybetű" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" -msgstr "" +msgstr "Kivágás" #: editor/plugins/script_text_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp @@ -4789,108 +4826,108 @@ msgstr "Másolás" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Select All" -msgstr "" +msgstr "Összes Kijelölése" #: editor/plugins/script_text_editor.cpp msgid "Delete Line" -msgstr "" +msgstr "Sor Törlése" #: editor/plugins/script_text_editor.cpp msgid "Indent Left" -msgstr "" +msgstr "Behúzás Balra" #: editor/plugins/script_text_editor.cpp msgid "Indent Right" -msgstr "" +msgstr "Behúzás Jobbra" #: editor/plugins/script_text_editor.cpp msgid "Toggle Comment" -msgstr "" - -#: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" +msgstr "Ãtváltás Megjegyzésre" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" -msgstr "" +msgstr "Sor Összezárása / Kibontása" #: editor/plugins/script_text_editor.cpp msgid "Fold All Lines" -msgstr "" +msgstr "Összes Sor Összezárása" #: editor/plugins/script_text_editor.cpp msgid "Unfold All Lines" -msgstr "" +msgstr "Összes Sor Kibontása" + +#: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Klónozás Lefelé" #: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" -msgstr "" +msgstr "Szimbólum Befejezése" #: editor/plugins/script_text_editor.cpp msgid "Trim Trailing Whitespace" -msgstr "" +msgstr "Sorvégi Szóközök LenyÃrása" #: editor/plugins/script_text_editor.cpp msgid "Convert Indent To Spaces" -msgstr "" +msgstr "Behúzások Ãtkonvertálása Szóközökre" #: editor/plugins/script_text_editor.cpp msgid "Convert Indent To Tabs" -msgstr "" +msgstr "Behúzások Ãtkonvertálása Tabokra" #: editor/plugins/script_text_editor.cpp msgid "Auto Indent" -msgstr "" +msgstr "Automatikus Behúzás" #: editor/plugins/script_text_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Toggle Breakpoint" -msgstr "" +msgstr "Töréspont Elhelyezése" #: editor/plugins/script_text_editor.cpp msgid "Remove All Breakpoints" -msgstr "" +msgstr "Összes Töréspont EltávolÃtása" #: editor/plugins/script_text_editor.cpp msgid "Goto Next Breakpoint" -msgstr "" +msgstr "Ugrás KövetkezÅ‘ Töréspontra" #: editor/plugins/script_text_editor.cpp msgid "Goto Previous Breakpoint" -msgstr "" +msgstr "Ugrás ElÅ‘zÅ‘ Töréspontra" #: editor/plugins/script_text_editor.cpp msgid "Convert To Uppercase" -msgstr "" +msgstr "Konvertálás Nagybetűsre" #: editor/plugins/script_text_editor.cpp msgid "Convert To Lowercase" -msgstr "" +msgstr "Konvertálás Kisbetűsre" #: editor/plugins/script_text_editor.cpp msgid "Find Previous" -msgstr "" +msgstr "ElÅ‘zÅ‘ Keresése" #: editor/plugins/script_text_editor.cpp msgid "Replace.." -msgstr "" +msgstr "Csere.." #: editor/plugins/script_text_editor.cpp msgid "Goto Function.." -msgstr "" +msgstr "Ugrás Funkcióra.." #: editor/plugins/script_text_editor.cpp msgid "Goto Line.." -msgstr "" +msgstr "Ugrás Sorra.." #: editor/plugins/script_text_editor.cpp msgid "Contextual Help" -msgstr "" +msgstr "Kontextusérzékeny Súgó" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" -msgstr "" +msgstr "Shader" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Change Scalar Constant" @@ -5664,11 +5701,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5928,10 +5960,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5952,7 +5980,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5972,10 +6002,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -5992,9 +6018,8 @@ msgid "Create New Project" msgstr "" #: editor/project_manager.cpp -#, fuzzy msgid "Create & Edit" -msgstr "Létrehozás" +msgstr "Létrehozás és Szerkesztés" #: editor/project_manager.cpp msgid "Install Project:" @@ -6657,18 +6682,13 @@ msgid "Error duplicating scene to save it." msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Sub-Resources" -msgstr "Forrás másolása" +msgstr "Al-ErÅ‘források" #: editor/scene_tree_dock.cpp msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6703,7 +6723,7 @@ msgstr "" #: editor/scene_tree_dock.cpp msgid "Copy Node Path" -msgstr "Node útvonal másaolása" +msgstr "Node Útvonal Másolása" #: editor/scene_tree_dock.cpp msgid "Delete (No Confirm)" @@ -6778,10 +6798,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -6958,9 +6974,8 @@ msgid "Child Process Connected" msgstr "" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Copy Error" -msgstr "Póz másolása" +msgstr "Hiba Másolása" #: editor/script_editor_debugger.cpp msgid "Inspect Previous Instance" @@ -7115,9 +7130,8 @@ msgid "Select dependencies of the library for this entry" msgstr "" #: modules/gdnative/gdnative_library_editor_plugin.cpp -#, fuzzy msgid "Remove current entry" -msgstr "Jelenlegi nyomvonal felfelé mozgatása." +msgstr "Jelenlegi tétel eltávolÃtása" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Double click to create a new entry" @@ -7163,11 +7177,12 @@ msgstr "" #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Invalid type argument to convert(), use TYPE_* constants." msgstr "" +"Érvénytelen tÃpus argumentum a convert()-hez használjon TYPE_* konstansokat." #: modules/gdscript/gdscript_functions.cpp modules/mono/glue/glue_header.h #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Not enough bytes for decoding bytes, or invalid format." -msgstr "" +msgstr "Nincs elég bájt a bájtok dekódolására, vagy hibás formátum." #: modules/gdscript/gdscript_functions.cpp msgid "step argument is zero!" @@ -7206,11 +7221,23 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +msgid "Next Plane" +msgstr "KövetkezÅ‘ SÃk" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Plane" +msgstr "ElÅ‘zÅ‘ SÃk" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7218,19 +7245,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7338,6 +7365,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7353,27 +7384,37 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " "properly!" msgstr "" +"Egy node munkamemória nélkül yield-elt, olvassa el a dokumentációt a yield " +"helyes használatáról!" #: modules/visual_script/visual_script.cpp msgid "" "Node yielded, but did not return a function state in the first working " "memory." msgstr "" +"A node yield-elt, de nem adta vissza funkció állapotot a legelsÅ‘ " +"munkamemóriában." #: modules/visual_script/visual_script.cpp msgid "" "Return value must be assigned to first element of node working memory! Fix " "your node please." msgstr "" +"A node munkamemóriájának elsÅ‘ elemének kell, hogy legyen visszatérési " +"értéke! JavÃtsa ki a node-ját." #: modules/visual_script/visual_script.cpp msgid "Node returned an invalid sequence output: " -msgstr "" +msgstr "Node egy érvénytelen szekvencia kimenettel tért vissza: " #: modules/visual_script/visual_script.cpp msgid "Found sequence bit but not the node in the stack, report bug!" @@ -7625,7 +7666,7 @@ msgstr "" #: modules/visual_script/visual_script_editor.cpp msgid "Copy Nodes" -msgstr "Node-ok másolása" +msgstr "Node-ok Másolása" #: modules/visual_script/visual_script_editor.cpp msgid "Cut Nodes" @@ -7852,6 +7893,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -7959,7 +8008,7 @@ msgstr "Figyelem!" #: scene/gui/dialogs.cpp msgid "Please Confirm..." -msgstr "Kérem erÅ‘sÃtse meg..." +msgstr "Kérem ErÅ‘sÃtse Meg..." #: scene/gui/file_dialog.cpp msgid "Select this Folder" @@ -7996,11 +8045,10 @@ msgid "" "obtain a size. Otherwise, make it a RenderTarget and assign its internal " "texture to some node for display." msgstr "" -"Ez a nézet nincs beállÃtva renderelési célnak. Ha azt szeretné, hogy a " -"tartalma közvetlenül a képernyÅ‘n jelenjen meg, akkor készÃtsen rajta egy " -"gyermek Control-t, Ãgy megkaphatja a méretét. EllenkezÅ‘ esetben készÃtsen " -"egy RenderTarget-et, és rendelje hozzá a belsÅ‘ textúrát egy Node-hoz a " -"megjelenÃtéshez." +"Ez a nézetablak nincs beállÃtva leképezési célnak. Ha azt szeretné, hogy a " +"tartalma közvetlenül a képernyÅ‘n jelenjen meg, tegye azt egy Control " +"gyermekévé, hogy Ãgy kapjon méretet. EllenkezÅ‘ esetben tegye RenderTarget-" +"té, és állÃtsa hozzá a belsÅ‘ textúráját valamilyen node-hoz kirajzolásra." #: scene/resources/dynamic_font.cpp msgid "Error initializing FreeType." @@ -8018,6 +8066,16 @@ msgstr "Hiba a betűtÃpus betöltésekor." msgid "Invalid font size." msgstr "Érvénytelen betűtÃpus méret." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Érvénytelen version.txt formátum a sablonokban. A revÃzió nem érvényes " +#~ "azonosÃtó." + +#~ msgid "Can't write file." +#~ msgstr "Nem lehet fájlt Ãrni." + #~ msgid "Next" #~ msgstr "KövetkezÅ‘" diff --git a/editor/translations/id.po b/editor/translations/id.po index ae7fd98ae2..df10490482 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -10,22 +10,22 @@ # Damar S. M <the.last.walla@gmail.com>, 2017. # Khairul Hidayat <khairulcyber4rt@gmail.com>, 2016. # Romi Kusuma Bakti <romikusumab@gmail.com>, 2017. -# Sofyan Sugianto <sofyanartem@gmail.com>, 2017. +# Sofyan Sugianto <sofyanartem@gmail.com>, 2017-2018. # Tom My <tom.asadinawan@gmail.com>, 2017. # yursan9 <rizal.sagi@gmail.com>, 2016. # msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2017-12-11 10:47+0000\n" -"Last-Translator: Romi Kusuma Bakti <romikusumab@gmail.com>\n" +"PO-Revision-Date: 2018-03-02 01:38+0000\n" +"Last-Translator: Sofyan Sugianto <sofyanartem@gmail.com>\n" "Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/" "godot/id/>\n" "Language: id\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2.18-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -36,9 +36,8 @@ msgid "All Selection" msgstr "Semua pilihan" #: editor/animation_editor.cpp -#, fuzzy msgid "Anim Change Keyframe Time" -msgstr "Ubah Nilai Animasi" +msgstr "Ubah Waktu Keyframe Animasi" #: editor/animation_editor.cpp msgid "Anim Change Transition" @@ -49,9 +48,8 @@ msgid "Anim Change Transform" msgstr "Ubah Transformasi Animasi" #: editor/animation_editor.cpp -#, fuzzy msgid "Anim Change Keyframe Value" -msgstr "Ubah Nilai Animasi" +msgstr "Ubah Nilai Keyframe Animasi" #: editor/animation_editor.cpp msgid "Anim Change Call" @@ -99,7 +97,7 @@ msgstr "Ubah Trek Anim ke Wrap Mode" #: editor/animation_editor.cpp msgid "Edit Node Curve" -msgstr "Edit Kurva Node" +msgstr "Sunting Kurva Node" #: editor/animation_editor.cpp msgid "Edit Selection Curve" @@ -380,9 +378,8 @@ msgid "No Matches" msgstr "Tidak ada yang cocok" #: editor/code_editor.cpp -#, fuzzy msgid "Replaced %d occurrence(s)." -msgstr "Diganti kejadian (kejadian-kejadian) %d." +msgstr "%d kejadian diganti." #: editor/code_editor.cpp msgid "Match Case" @@ -504,9 +501,8 @@ msgid "Connecting Signal:" msgstr "Menyambungkan Sinyal:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Disconnect '%s' from '%s'" -msgstr "Sambungkan '%s' ke '%s'" +msgstr "Memutuskan '%s' dari '%s'" #: editor/connections_dialog.cpp msgid "Connect.." @@ -522,9 +518,8 @@ msgid "Signals" msgstr "Sinyal-sinyal" #: editor/create_dialog.cpp -#, fuzzy msgid "Change %s Type" -msgstr "Ubah Tipe Nilai Array" +msgstr "Ubah Tipe %s" #: editor/create_dialog.cpp editor/project_settings_editor.cpp #: modules/visual_script/visual_script_editor.cpp @@ -532,9 +527,8 @@ msgid "Change" msgstr "Ubah" #: editor/create_dialog.cpp -#, fuzzy msgid "Create New %s" -msgstr "Buat Baru" +msgstr "Buat Baru %s" #: editor/create_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp @@ -612,9 +606,8 @@ msgid "Fix Broken" msgstr "Perbaiki yang Rusak" #: editor/dependency_editor.cpp -#, fuzzy msgid "Dependency Editor" -msgstr "Editor Ketergantungan" +msgstr "Penyunting Dependensi" #: editor/dependency_editor.cpp msgid "Search Replacement Resource:" @@ -647,9 +640,8 @@ msgstr "" "Hapus saja? (tidak bisa dibatalkan/undo)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Cannot remove:" -msgstr "Tidak bisa dibuang:\n" +msgstr "Tidak bisa menghapus:" #: editor/dependency_editor.cpp msgid "Error loading:" @@ -710,7 +702,7 @@ msgstr "Ubah Kunci Kamus" #: editor/dictionary_property_edit.cpp #, fuzzy msgid "Change Dictionary Value" -msgstr "Ubah Nilai Array" +msgstr "Ubah Nilai Dictionary" #: editor/editor_about.cpp msgid "Thanks from the Godot community!" @@ -733,9 +725,8 @@ msgid "Lead Developer" msgstr "Pengembang Utama" #: editor/editor_about.cpp -#, fuzzy msgid "Project Manager " -msgstr "Manajer Proyek" +msgstr "Manajer Proyek " #: editor/editor_about.cpp msgid "Developers" @@ -794,14 +785,12 @@ msgstr "" "lisensi masing-masing." #: editor/editor_about.cpp -#, fuzzy msgid "All Components" -msgstr "Konstanta:" +msgstr "Semua Komponen" #: editor/editor_about.cpp -#, fuzzy msgid "Components" -msgstr "Konstanta:" +msgstr "Komponen" #: editor/editor_about.cpp msgid "Licenses" @@ -812,9 +801,8 @@ msgid "Error opening package file, not in zip format." msgstr "Gagal saat membuka paket, tidak dalam bentuk zip." #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Uncompressing Assets" -msgstr "Mengimpor ulang" +msgstr "Membuka Aset Terkompresi" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Package Installed Successfully!" @@ -843,14 +831,12 @@ msgid "Add Effect" msgstr "Tambahkan Efek" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Rename Audio Bus" -msgstr "Namai kembali Autoload" +msgstr "Ubah Nama Bus Audio" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Change Audio Bus Volume" -msgstr "Alih Audio Bus Solo" +msgstr "Ubah Volume Bus Audio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Solo" @@ -877,9 +863,8 @@ msgid "Move Bus Effect" msgstr "Pindah Efek Bus" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Delete Bus Effect" -msgstr "Hapus yang Dipilih" +msgstr "Hapus Effect Bus" #: editor/editor_audio_buses.cpp msgid "Audio Bus, Drag and Drop to rearrange." @@ -907,18 +892,16 @@ msgid "Duplicate" msgstr "Gandakan" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Reset Volume" -msgstr "Kebalikan Semula Pandangan" +msgstr "Setel Ulang Volume" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Delete Effect" -msgstr "Hapus yang Dipilih" +msgstr "Hapus Efek" #: editor/editor_audio_buses.cpp msgid "Audio" -msgstr "" +msgstr "Suara" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus" @@ -931,22 +914,20 @@ msgstr "Master Bus tidak dapat dihapus!" #: editor/editor_audio_buses.cpp #, fuzzy msgid "Delete Audio Bus" -msgstr "Hapus Penampilan" +msgstr "Hapus Bus Audio" #: editor/editor_audio_buses.cpp #, fuzzy msgid "Duplicate Audio Bus" -msgstr "Duplikat Pilihan" +msgstr "Duplikat Audio Bus" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Reset Bus Volume" -msgstr "Kebalikan Semula Pandangan" +msgstr "Setel Ulang Bus Volume" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Move Audio Bus" -msgstr "Pindahkan Kunci Tambah" +msgstr "Pindahkan Audio Bus" #: editor/editor_audio_buses.cpp msgid "Save Audio Bus Layout As.." @@ -997,7 +978,7 @@ msgstr "Simpan Layout Bus ke berkas." #: editor/editor_audio_buses.cpp editor/import_dock.cpp #, fuzzy msgid "Load Default" -msgstr "Bawaan" +msgstr "Muat Konfigurasi Bawaan" #: editor/editor_audio_buses.cpp msgid "Load the default Bus Layout." @@ -1012,9 +993,9 @@ msgid "Valid characters:" msgstr "Karakter sah:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Invalid name. Must not collide with an existing engine class name." -msgstr "Nama tidak sah. Harus tidak serupa dengan class name engine yang ada." +msgstr "" +"Nama tidak valid. Tidak boleh sama dengan nama kelas bawaan engine yang ada." #: editor/editor_autoload_settings.cpp msgid "Invalid name. Must not collide with an existing buit-in type name." @@ -1062,7 +1043,6 @@ msgid "Remove Autoload" msgstr "Hapus Autoload" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Enable" msgstr "Aktifkan" @@ -1102,16 +1082,16 @@ msgstr "Memperbaharui scene.." #: editor/editor_data.cpp msgid "[empty]" -msgstr "" +msgstr "[kosong]" #: editor/editor_data.cpp msgid "[unsaved]" -msgstr "" +msgstr "[belum disimpan]" #: editor/editor_dir_dialog.cpp #, fuzzy msgid "Please select a base directory first" -msgstr "Mohon simpan scene terlebih dahulu." +msgstr "Pilih direktori kerja terlebih dahulu" #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1147,31 +1127,28 @@ msgid "Packing" msgstr "Mengemas" #: editor/editor_export.cpp platform/javascript/export/export.cpp -#, fuzzy msgid "Template file not found:" -msgstr "Template berkas tidak ditemukan:\n" +msgstr "Templat berkas tidak ditemukan:" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File Exists, Overwrite?" msgstr "File telah ada, Overwrite?" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Select Current Folder" -msgstr "Buat Folder" +msgstr "Pilih Folder Saat Ini" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "Copy Path" -msgstr "" +msgstr "Salin Lokasi" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "Show In File Manager" msgstr "Tampilkan di Manajer Berkas" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "New Folder.." -msgstr "Buat Folder" +msgstr "Buat Direktori..." #: editor/editor_file_dialog.cpp msgid "Refresh" @@ -1212,17 +1189,14 @@ msgid "Save a File" msgstr "Simpan sebuah File" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Go Back" -msgstr "Mundur" +msgstr "Kembali" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Go Forward" msgstr "Maju" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Go Up" msgstr "Naik" @@ -1251,9 +1225,8 @@ msgid "Move Favorite Down" msgstr "Pindahkan Favorit Kebawah" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Go to parent folder" -msgstr "Tidak dapat membuat folder." +msgstr "Pergi ke direktori induk" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Directories & Files:" @@ -1277,9 +1250,8 @@ msgid "ScanSources" msgstr "Sumber Pemindaian" #: editor/editor_file_system.cpp -#, fuzzy msgid "(Re)Importing Assets" -msgstr "Mengimpor ulang" +msgstr "Mengimpor ulang Aset" #: editor/editor_help.cpp editor/editor_node.cpp #: editor/plugins/script_editor_plugin.cpp @@ -1315,9 +1287,8 @@ msgid "Brief Description:" msgstr "Deskripsi Singkat:" #: editor/editor_help.cpp -#, fuzzy msgid "Members" -msgstr "Member-member:" +msgstr "Anggota" #: editor/editor_help.cpp modules/visual_script/visual_script_editor.cpp msgid "Members:" @@ -1326,7 +1297,7 @@ msgstr "Member-member:" #: editor/editor_help.cpp #, fuzzy msgid "Public Methods" -msgstr "Metode Publik:" +msgstr "Fungsi Publik" #: editor/editor_help.cpp msgid "Public Methods:" @@ -1346,57 +1317,50 @@ msgid "Signals:" msgstr "Sinyal-sinyal:" #: editor/editor_help.cpp -#, fuzzy msgid "Enumerations" -msgstr "Fungsi-fungsi:" +msgstr "Enumerasi" #: editor/editor_help.cpp -#, fuzzy msgid "Enumerations:" -msgstr "Fungsi-fungsi:" +msgstr "Enumerasi:" #: editor/editor_help.cpp msgid "enum " -msgstr "" +msgstr "enum " #: editor/editor_help.cpp -#, fuzzy msgid "Constants" -msgstr "Konstanta:" +msgstr "Konstanta" #: editor/editor_help.cpp msgid "Constants:" msgstr "Konstanta:" #: editor/editor_help.cpp -#, fuzzy msgid "Description" -msgstr "Deskripsi:" +msgstr "Deskripsi" #: editor/editor_help.cpp -#, fuzzy msgid "Online Tutorials:" -msgstr "Online Dokumentasi" +msgstr "Tutorial Daring:" #: editor/editor_help.cpp -#, fuzzy msgid "" "There are currently no tutorials for this class, you can [color=$color][url=" "$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/" "url][/color]." msgstr "" -"Untuk saat ini tidak ada deskripsi metode ini. Tolong bantu kita dengan " -"[color=$color][url=$url]kontribusi[/url][/color]!" +"Untuk saat ini tidak ada tutorial dalam kelas ini, anda bisa [color=$color]" +"[url=$url]ikut berkontribusi[/url][/color] atau [color=$color][url=" +"$url2]memberikan usulan[/url][/color]." #: editor/editor_help.cpp -#, fuzzy msgid "Properties" -msgstr "Properti Objek." +msgstr "Properti Objek" #: editor/editor_help.cpp -#, fuzzy msgid "Property Description:" -msgstr "Deskripsi Singkat:" +msgstr "Deskripsi Properti Objek:" #: editor/editor_help.cpp msgid "" @@ -1407,9 +1371,8 @@ msgstr "" "dengan[color=$color][url=$url]kontribusi[/url][/color]!" #: editor/editor_help.cpp -#, fuzzy msgid "Methods" -msgstr "Daftar Fungsi:" +msgstr "Fungsi" #: editor/editor_help.cpp msgid "Method Description:" @@ -1432,9 +1395,8 @@ msgid "Find" msgstr "Cari" #: editor/editor_log.cpp -#, fuzzy msgid "Output:" -msgstr " Keluaran:" +msgstr "Keluaran:" #: editor/editor_log.cpp editor/plugins/animation_tree_editor_plugin.cpp #: editor/property_editor.cpp editor/script_editor_debugger.cpp @@ -1444,9 +1406,8 @@ msgid "Clear" msgstr "Bersihkan" #: editor/editor_log.cpp -#, fuzzy msgid "Clear Output" -msgstr "Luaran" +msgstr "Bersihkan Luaran" #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Error saving resource!" @@ -1475,28 +1436,24 @@ msgid "Error while saving." msgstr "Error saat menyimpan." #: editor/editor_node.cpp -#, fuzzy msgid "Can't open '%s'." -msgstr "Menyambungkan.." +msgstr "Tidak dapat membuka '%s'." #: editor/editor_node.cpp -#, fuzzy msgid "Error while parsing '%s'." -msgstr "Error saat menyimpan." +msgstr "Kesalahan saat melakukan parsing '%s'." #: editor/editor_node.cpp msgid "Unexpected end of file '%s'." msgstr "akhir dari berkas tak terduga '%s'." #: editor/editor_node.cpp -#, fuzzy msgid "Missing '%s' or its dependencies." -msgstr "Scene '%s' memiliki dependensi yang rusak:" +msgstr "'%s' hilang atau memiliki dependensi yang rusak." #: editor/editor_node.cpp -#, fuzzy msgid "Error while loading '%s'." -msgstr "Error saat menyimpan." +msgstr "Terjadi kesalahan saat memuat '%s'." #: editor/editor_node.cpp msgid "Saving Scene" @@ -1513,15 +1470,15 @@ msgstr "Membuat Thumbnail" #: editor/editor_node.cpp #, fuzzy msgid "This operation can't be done without a tree root." -msgstr "Tindakan ini tidak dapat dibatalkan. Pulihkan saja?" +msgstr "Tindakan ini tidak bisa dilakukan tanpa \"tree root\"" #: editor/editor_node.cpp -#, fuzzy msgid "" "Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " "be satisfied." msgstr "" -"Tidak dapat menyimpan scene. Dependensi (instance) mungkin tidak terpenuhi." +"Tidak dapat menyimpan scene. Dependensi (instance atau turunannya) mungkin " +"tidak terpenuhi." #: editor/editor_node.cpp msgid "Failed to load resource." @@ -1532,9 +1489,8 @@ msgid "Can't load MeshLibrary for merging!" msgstr "Tidak dapat memuat MeshLibrary untuk menggabungkan!" #: editor/editor_node.cpp -#, fuzzy msgid "Error saving MeshLibrary!" -msgstr "Error menyimpan MeshLibrary!" +msgstr "Terjadi kesalahan saat menyimpan MeshLibrary!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" @@ -1650,15 +1606,14 @@ msgid "There is no defined scene to run." msgstr "Tidak ada definisi scene untuk dijalankan." #: editor/editor_node.cpp -#, fuzzy msgid "" "No main scene has ever been defined, select one?\n" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" "Tidak ada scene utama yang pernah didefinisikan, pilih satu?\n" -"Anda dapat mengubahnya nanti di akhir dalam \"Project Settings\" dibawah " -"kategori 'application'." +"Anda dapat mengubahnya nanti di \"Project Settings\" di bawah kategori " +"'application'." #: editor/editor_node.cpp msgid "" @@ -1707,9 +1662,8 @@ msgid "Quick Open Script.." msgstr "Buka Cepat Script.." #: editor/editor_node.cpp -#, fuzzy msgid "Save & Close" -msgstr "Simpan sebuah File" +msgstr "Simpan & Tutup" #: editor/editor_node.cpp msgid "Save changes to '%s' before closing?" @@ -1740,9 +1694,8 @@ msgid "Export Mesh Library" msgstr "Ekspor Mesh Library" #: editor/editor_node.cpp -#, fuzzy msgid "This operation can't be done without a root node." -msgstr "Tindakan ini tidak dapat dibatalkan. Pulihkan saja?" +msgstr "Tindakan ini tidak bisa dilakukan tanpa node dasar." #: editor/editor_node.cpp msgid "Export Tile Set" @@ -1785,19 +1738,16 @@ msgid "Open Project Manager?" msgstr "Buka Project Manager?" #: editor/editor_node.cpp -#, fuzzy msgid "Save & Quit" -msgstr "Simpan sebuah File" +msgstr "Simpan & Keluar" #: editor/editor_node.cpp -#, fuzzy msgid "Save changes to the following scene(s) before quitting?" -msgstr "Simpan perubahan saat ini sebelum keluar?" +msgstr "Simpan perubahan scene saat ini sebelum keluar?" #: editor/editor_node.cpp -#, fuzzy msgid "Save changes the following scene(s) before opening Project Manager?" -msgstr "Simpan perubahan saat ini sebelum membuka Manajer Projek?" +msgstr "Simpan perubahan scene saat ini sebelum membuka Manajer Projek?" #: editor/editor_node.cpp msgid "" @@ -1823,9 +1773,8 @@ msgstr "" "Tidak dapat mencari bidang script untuk addon plugin pada: 'res://addons/%s'." #: editor/editor_node.cpp -#, fuzzy msgid "Unable to load addon script from path: '%s'." -msgstr "Error memuat font." +msgstr "Tidak bisa memuat script addon dari lokasi: '%s'." #: editor/editor_node.cpp msgid "" @@ -1887,17 +1836,14 @@ msgid "Switch Scene Tab" msgstr "Pilih Tab Scene" #: editor/editor_node.cpp -#, fuzzy msgid "%d more files or folders" msgstr "%d file atau folder lagi" #: editor/editor_node.cpp -#, fuzzy msgid "%d more folders" -msgstr "%d file lagi" +msgstr "%d folder lagi" #: editor/editor_node.cpp -#, fuzzy msgid "%d more files" msgstr "%d file lagi" @@ -1915,9 +1861,8 @@ msgid "Toggle distraction-free mode." msgstr "Mode Tanpa Gangguan" #: editor/editor_node.cpp -#, fuzzy msgid "Add a new scene." -msgstr "Tambah tracks baru." +msgstr "Tambah scene baru." #: editor/editor_node.cpp msgid "Scene" @@ -2117,9 +2062,8 @@ msgstr "" "jaringan filesystem." #: editor/editor_node.cpp -#, fuzzy msgid "Editor" -msgstr "Edit" +msgstr "Editor" #: editor/editor_node.cpp editor/settings_config_dialog.cpp msgid "Editor Settings" @@ -2130,14 +2074,12 @@ msgid "Editor Layout" msgstr "Tata Letak Editor" #: editor/editor_node.cpp -#, fuzzy msgid "Toggle Fullscreen" msgstr "Mode Layar Penuh" #: editor/editor_node.cpp editor/project_export.cpp -#, fuzzy msgid "Manage Export Templates" -msgstr "Memuat Ekspor Template-template." +msgstr "Mengatur Templat Ekspor" #: editor/editor_node.cpp msgid "Help" @@ -2145,7 +2087,7 @@ msgstr "Bantuan" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Classes" -msgstr "" +msgstr "Kelas" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp @@ -2160,7 +2102,7 @@ msgstr "Online Dokumentasi" #: editor/editor_node.cpp msgid "Q&A" -msgstr "" +msgstr "Tanya Jawab" #: editor/editor_node.cpp msgid "Issue Tracker" @@ -2184,11 +2126,11 @@ msgstr "Mainkan" #: editor/editor_node.cpp msgid "Pause the scene" -msgstr "" +msgstr "Hentikan sementara scene ini" #: editor/editor_node.cpp msgid "Pause Scene" -msgstr "" +msgstr "Hentikan Sementara Scene" #: editor/editor_node.cpp msgid "Stop the scene." @@ -2276,9 +2218,8 @@ msgid "Import" msgstr "Impor" #: editor/editor_node.cpp -#, fuzzy msgid "Node" -msgstr "Titik" +msgstr "" #: editor/editor_node.cpp msgid "FileSystem" @@ -2293,7 +2234,6 @@ msgid "Don't Save" msgstr "Jangan Simpan" #: editor/editor_node.cpp -#, fuzzy msgid "Import Templates From ZIP File" msgstr "Impor Templat dari Berkas ZIP" @@ -2306,7 +2246,6 @@ msgid "Export Library" msgstr "Ekspor Pustaka" #: editor/editor_node.cpp -#, fuzzy msgid "Merge With Existing" msgstr "Gabung dengan yang Ada" @@ -2319,12 +2258,10 @@ msgid "Open & Run a Script" msgstr "Buka & Jalankan Skrip" #: editor/editor_node.cpp -#, fuzzy msgid "New Inherited" -msgstr "Scene Turunan Baru.." +msgstr "Turunan Baru" #: editor/editor_node.cpp -#, fuzzy msgid "Load Errors" msgstr "Muat Galat" @@ -2333,12 +2270,10 @@ msgid "Select" msgstr "Pilih" #: editor/editor_node.cpp -#, fuzzy msgid "Open 2D Editor" msgstr "Buka Penyunting 2D" #: editor/editor_node.cpp -#, fuzzy msgid "Open 3D Editor" msgstr "Buka Penyunting 3D" @@ -2385,7 +2320,7 @@ msgstr "Pembuat:" #: editor/editor_plugin_settings.cpp msgid "Status:" -msgstr "" +msgstr "Status:" #: editor/editor_profiler.cpp msgid "Stop Profiling" @@ -2432,12 +2367,10 @@ msgid "Frame #:" msgstr "Bingkai #:" #: editor/editor_profiler.cpp -#, fuzzy msgid "Time" -msgstr "Waktu:" +msgstr "Waktu" #: editor/editor_profiler.cpp -#, fuzzy msgid "Calls" msgstr "Panggil" @@ -2450,79 +2383,80 @@ msgid "" "No runnable export preset found for this platform.\n" "Please add a runnable preset in the export menu." msgstr "" +"Tidak ada preset ekspor yang bisa digunakan untuk platform ini.\n" +"Mohon tambahkan preset yang bisa digunakan di menu ekspor." #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." -msgstr "" +msgstr "Tulis logika di dalam fungsi _run()." #: editor/editor_run_script.cpp msgid "There is an edited scene already." -msgstr "" +msgstr "Ada scene yang disunting." #: editor/editor_run_script.cpp msgid "Couldn't instance script:" -msgstr "" +msgstr "Tidak bisa meng-instance script:" #: editor/editor_run_script.cpp msgid "Did you forget the 'tool' keyword?" -msgstr "" +msgstr "Apakah anda lupa dengan kata kunci 'tool'?" #: editor/editor_run_script.cpp msgid "Couldn't run script:" -msgstr "" +msgstr "Tidak bisa menjalankan script:" #: editor/editor_run_script.cpp msgid "Did you forget the '_run' method?" -msgstr "" +msgstr "Apakah anda lupa dengan fungsi '_run' ?" #: editor/editor_settings.cpp msgid "Default (Same as Editor)" -msgstr "" +msgstr "Baku (Samakan seperti Penyunting saat ini)" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" -msgstr "" +msgstr "Pilih node untuk diimpor" #: editor/editor_sub_scene.cpp msgid "Scene Path:" -msgstr "" +msgstr "Lokasi Scene:" #: editor/editor_sub_scene.cpp msgid "Import From Node:" -msgstr "" +msgstr "Impor dari Node:" #: editor/export_template_manager.cpp msgid "Re-Download" -msgstr "" +msgstr "Unduh Ulang" #: editor/export_template_manager.cpp msgid "Uninstall" -msgstr "" +msgstr "Copot Pemasangan" #: editor/export_template_manager.cpp msgid "(Installed)" -msgstr "" +msgstr "(terpasang)" #: editor/export_template_manager.cpp msgid "Download" -msgstr "" +msgstr "Unduh" #: editor/export_template_manager.cpp msgid "(Missing)" -msgstr "" +msgstr "(hilang)" #: editor/export_template_manager.cpp msgid "(Current)" -msgstr "" +msgstr "(Kondisi Saat Ini)" #: editor/export_template_manager.cpp -#, fuzzy msgid "Retrieving mirrors, please wait.." -msgstr "Gangguan koneks, silakan coba lagi." +msgstr "Mendapatkan informasi cermin, silakan tunggu.." #: editor/export_template_manager.cpp msgid "Remove template version '%s'?" -msgstr "" +msgstr "Hapus templat versi '%s'?" #: editor/export_template_manager.cpp msgid "Can't open export templates zip." @@ -2530,27 +2464,19 @@ msgstr "Tidak dapat membuka ekspor template-template zip." #: editor/export_template_manager.cpp msgid "Invalid version.txt format inside templates." -msgstr "" - -#: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" +msgstr "Format version.txt tidak valid dalam berkas templat." #: editor/export_template_manager.cpp msgid "No version.txt found inside templates." -msgstr "" +msgstr "Berkas version.txt tidak ditemukan dalam templat." #: editor/export_template_manager.cpp -#, fuzzy msgid "Error creating path for templates:" -msgstr "Gagal menyimpan atlas:" +msgstr "Kesalahan saat membuat lokasi untuk templat:" #: editor/export_template_manager.cpp -#, fuzzy msgid "Extracting Export Templates" -msgstr "Memuat Ekspor Template-template." +msgstr "Mengekstrak Berkas Templat Ekspor" #: editor/export_template_manager.cpp msgid "Importing:" @@ -2561,17 +2487,18 @@ msgid "" "No download links found for this version. Direct download is only available " "for official releases." msgstr "" +"Tautan unduh tidak ditemukan untuk versi ini. Unduhan langsung hanya " +"tersedia untuk versi rilis resmi." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve." -msgstr "" +msgstr "Tidak bisa menyelesaikan." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Can't connect." -msgstr "Menyambungkan.." +msgstr "Tidak dapat terhubung." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -2580,9 +2507,8 @@ msgstr "Tidak ada respon." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Request Failed." -msgstr "Menguji" +msgstr "Permintaan Gagal." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -2592,31 +2518,23 @@ msgstr "" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed:" -msgstr "" - -#: editor/export_template_manager.cpp -#, fuzzy -msgid "Can't write file." -msgstr "Tidak dapat membuat folder." +msgstr "Gagal:" #: editor/export_template_manager.cpp msgid "Download Complete." -msgstr "" +msgstr "Unduhan Selesai." #: editor/export_template_manager.cpp -#, fuzzy msgid "Error requesting url: " -msgstr "Gagal menyimpan atlas:" +msgstr "Kesalahan saat meminta url: " #: editor/export_template_manager.cpp -#, fuzzy msgid "Connecting to Mirror.." msgstr "Menyambungkan.." #: editor/export_template_manager.cpp -#, fuzzy msgid "Disconnected" -msgstr "Tidak tersambung" +msgstr "Terputus" #: editor/export_template_manager.cpp msgid "Resolving" @@ -2628,160 +2546,146 @@ msgstr "" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Connecting.." msgstr "Menyambungkan.." #: editor/export_template_manager.cpp -#, fuzzy msgid "Can't Connect" -msgstr "Menyambungkan.." +msgstr "Tidak dapat terhubung" #: editor/export_template_manager.cpp -#, fuzzy msgid "Connected" -msgstr "Menghubungkan" +msgstr "Terhubung" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Requesting.." -msgstr "Menguji" +msgstr "Melakukan permintaan.." #: editor/export_template_manager.cpp -#, fuzzy msgid "Downloading" -msgstr "Error memuat:" +msgstr "Mengunduh" #: editor/export_template_manager.cpp -#, fuzzy msgid "Connection Error" -msgstr "Menyambungkan.." +msgstr "Gangguan Koneksi" #: editor/export_template_manager.cpp -#, fuzzy msgid "SSL Handshake Error" -msgstr "Muat Galat" +msgstr "Kesalahan jabat tangan SSL" #: editor/export_template_manager.cpp msgid "Current Version:" -msgstr "" +msgstr "Versi sekarang:" #: editor/export_template_manager.cpp msgid "Installed Versions:" -msgstr "" +msgstr "Versi Terpasang:" #: editor/export_template_manager.cpp msgid "Install From File" -msgstr "" +msgstr "Memasang dari berkas" #: editor/export_template_manager.cpp -#, fuzzy msgid "Remove Template" -msgstr "Hapus Pilihan" +msgstr "Hapus Templat" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select template file" -msgstr "Hapus file yang dipilih?" +msgstr "Pilih berkas templat" #: editor/export_template_manager.cpp -#, fuzzy msgid "Export Template Manager" -msgstr "Memuat Ekspor Template-template." +msgstr "Manajer Templat Ekspor" #: editor/export_template_manager.cpp -#, fuzzy msgid "Download Templates" -msgstr "Hapus Pilihan" +msgstr "Unduh Templat" #: editor/export_template_manager.cpp msgid "Select mirror from list: " -msgstr "" +msgstr "Pilih cermin dari daftar: " #: editor/file_type_cache.cpp msgid "Can't open file_type_cache.cch for writing, not saving file type cache!" msgstr "" +"Tidak dapat membuka file_type_cache.cch untuk menulis, berkas cache tidak " +"disimpan!" #: editor/filesystem_dock.cpp msgid "Cannot navigate to '%s' as it has not been found in the file system!" msgstr "" +"'%s' tidak bisa ditelusuri karena tidak bisa ditemukan dalam berkas sistem!" #: editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails" -msgstr "" +msgstr "Tampilkan item sebagai grid thumbnail" #: editor/filesystem_dock.cpp msgid "View items as a list" -msgstr "" +msgstr "Tampilkan item sebagai daftar" #: editor/filesystem_dock.cpp msgid "Status: Import of file failed. Please fix file and reimport manually." msgstr "" +"Status: Gagal mengimpor berkas. Mohon perbaiki berkas dan impor ulang secara " +"manual." #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." -msgstr "" +msgstr "Tidak bisa memindah/mengubah nama aset root." #: editor/filesystem_dock.cpp msgid "Cannot move a folder into itself." -msgstr "" +msgstr "Tidak dapat memindahkan folder ke dalam dirinya sendiri." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Error moving:" -msgstr "Error memuat:" +msgstr "Galat saat memindahkan:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Error duplicating:" -msgstr "Error saat memuat:" +msgstr "Galat saat menggandakan berkas:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Unable to update dependencies:" -msgstr "Scene '%s' memiliki dependensi yang rusak:" +msgstr "Tidak bisa memperbarui dependensi:" #: editor/filesystem_dock.cpp msgid "No name provided" -msgstr "" +msgstr "Nama masih kosong" #: editor/filesystem_dock.cpp msgid "Provided name contains invalid characters" -msgstr "" +msgstr "Nama yang dimasukkan tidak valid" #: editor/filesystem_dock.cpp -#, fuzzy msgid "No name provided." -msgstr "Ubah Nama atau Pindahkan.." +msgstr "Nama masih kosong." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Name contains invalid characters." -msgstr "Karakter sah:" +msgstr "Nama mengandung karakter tidak valid." #: editor/filesystem_dock.cpp msgid "A file or folder with this name already exists." -msgstr "" +msgstr "Sudah ada nama berkas atau folder seperti itu." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Renaming file:" -msgstr "Namai kembali Variabel" +msgstr "Mengubah nama berkas dengan:" #: editor/filesystem_dock.cpp msgid "Renaming folder:" -msgstr "" +msgstr "Mengubah nama folder dengan:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Duplicating file:" -msgstr "Gandakan" +msgstr "Menggandakan berkas:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Duplicating folder:" -msgstr "Gandakan" +msgstr "Menggandakan folder:" #: editor/filesystem_dock.cpp msgid "Expand all" @@ -2792,16 +2696,14 @@ msgid "Collapse all" msgstr "" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Rename.." -msgstr "Ubah Nama atau Pindahkan.." +msgstr "Ubah Nama.." #: editor/filesystem_dock.cpp msgid "Move To.." -msgstr "Pindah Ke.." +msgstr "Pindahkan ke.." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scene(s)" msgstr "Buka Scene" @@ -2811,16 +2713,15 @@ msgstr "" #: editor/filesystem_dock.cpp msgid "Edit Dependencies.." -msgstr "" +msgstr "Sunting Dependensi.." #: editor/filesystem_dock.cpp msgid "View Owners.." -msgstr "" +msgstr "Tampilkan Pemilik Berkas.." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Duplicate.." -msgstr "Gandakan" +msgstr "Gandakan.." #: editor/filesystem_dock.cpp msgid "Previous Directory" @@ -2836,14 +2737,13 @@ msgstr "Pindai Ulang Berkas Sistem" #: editor/filesystem_dock.cpp msgid "Toggle folder status as Favorite" -msgstr "" +msgstr "Kondisikan status folder sebagai Favorit" #: editor/filesystem_dock.cpp msgid "Instance the selected scene(s) as child of the selected node." -msgstr "" +msgstr "Instance scene terpilih sebagai anak node saat ini." #: editor/filesystem_dock.cpp -#, fuzzy msgid "" "Scanning Files,\n" "Please Wait.." @@ -2858,7 +2758,7 @@ msgstr "Pindahkan" #: editor/filesystem_dock.cpp editor/plugins/animation_tree_editor_plugin.cpp #: editor/project_manager.cpp msgid "Rename" -msgstr "" +msgstr "Ubah Nama" #: editor/groups_editor.cpp msgid "Add to Group" @@ -2866,112 +2766,110 @@ msgstr "Tambahkan ke Grup" #: editor/groups_editor.cpp msgid "Remove from Group" -msgstr "" +msgstr "Hapus dari Grup" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Import as Single Scene" -msgstr "Memperbaharui Scene" +msgstr "Impor sebagai Scene Tunggal" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Animations" -msgstr "" +msgstr "Impor dengan Animasi Terpisah" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials" -msgstr "" +msgstr "Impor dengan Material Terpisah" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects" -msgstr "" +msgstr "Impor dengan Objek Terpisah" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials" -msgstr "" +msgstr "Impor dengan Objek+Material Terpisah" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Animations" -msgstr "" +msgstr "Impor dengan Objek+Animasi Terpisah" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials+Animations" -msgstr "" +msgstr "Impor dengan Material+Animasi Terpisah" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials+Animations" -msgstr "" +msgstr "Impor dengan Objek+Material+Animasi Terpisah" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes" -msgstr "" +msgstr "Impor sebagai Beberapa Scene" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes+Materials" -msgstr "" +msgstr "Impor Beberapa Scene+Material" #: editor/import/resource_importer_scene.cpp #: editor/plugins/cube_grid_theme_editor_plugin.cpp msgid "Import Scene" -msgstr "" +msgstr "Impor Scene" #: editor/import/resource_importer_scene.cpp msgid "Importing Scene.." -msgstr "" +msgstr "Mengimpor scene.." #: editor/import/resource_importer_scene.cpp +#, fuzzy msgid "Generating Lightmaps" -msgstr "" +msgstr "Sedang Membuat Pemetaan Cahaya" #: editor/import/resource_importer_scene.cpp msgid "Generating for Mesh: " msgstr "" #: editor/import/resource_importer_scene.cpp +#, fuzzy msgid "Running Custom Script.." -msgstr "" +msgstr "Menjalankan Skrip Buatan.." #: editor/import/resource_importer_scene.cpp msgid "Couldn't load post-import script:" -msgstr "" +msgstr "Tidak dapat memuat skrip post-import:" #: editor/import/resource_importer_scene.cpp msgid "Invalid/broken script for post-import (check console):" -msgstr "" +msgstr "Skrip post-import rusak/tidak valid (cek konsol):" #: editor/import/resource_importer_scene.cpp msgid "Error running post-import script:" -msgstr "" +msgstr "Kesalahan saat menjalankan skrip post-import:" #: editor/import/resource_importer_scene.cpp msgid "Saving.." -msgstr "" +msgstr "Menyimpan.." #: editor/import_dock.cpp msgid "Set as Default for '%s'" -msgstr "" +msgstr "Jadikan Baku untuk '%s'" #: editor/import_dock.cpp msgid "Clear Default for '%s'" -msgstr "" +msgstr "Bersihkan Baku untuk '%s'" #: editor/import_dock.cpp -#, fuzzy msgid " Files" -msgstr "File:" +msgstr " Berkas" #: editor/import_dock.cpp -#, fuzzy msgid "Import As:" -msgstr "Mengimpor:" +msgstr "Impor sebagai:" #: editor/import_dock.cpp editor/property_editor.cpp msgid "Preset.." msgstr "" #: editor/import_dock.cpp -#, fuzzy msgid "Reimport" -msgstr "Mengimpor ulang" +msgstr "Impor ulang" #: editor/multi_node_edit.cpp msgid "MultiNode Set" @@ -2979,97 +2877,105 @@ msgstr "" #: editor/node_dock.cpp msgid "Groups" -msgstr "" +msgstr "Grup" #: editor/node_dock.cpp msgid "Select a Node to edit Signals and Groups." -msgstr "" +msgstr "Pilih sebuah node untuk menyunting Sinyal dan Grup." #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp +#, fuzzy msgid "Create Poly" -msgstr "" +msgstr "Buat Bidang" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/collision_polygon_editor_plugin.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp +#, fuzzy msgid "Edit Poly" -msgstr "" +msgstr "Sunting Bidang" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Insert Point" -msgstr "" +msgstr "Tambah Titik" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/collision_polygon_editor_plugin.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Edit Poly (Remove Point)" -msgstr "" +msgstr "Sunting Bidang (Hapus Titik)" #: editor/plugins/abstract_polygon_2d_editor.cpp +#, fuzzy msgid "Remove Poly And Point" -msgstr "" +msgstr "Hapus Bidang dan Titik" #: editor/plugins/abstract_polygon_2d_editor.cpp +#, fuzzy msgid "Create a new polygon from scratch" -msgstr "" +msgstr "Buat bidang baru dari awal" #: editor/plugins/abstract_polygon_2d_editor.cpp +#, fuzzy msgid "" "Edit existing polygon:\n" "LMB: Move Point.\n" "Ctrl+LMB: Split Segment.\n" "RMB: Erase Point." msgstr "" +"Sunting bidang yang ada:\n" +"LMB: Pindahkan Titik.\n" +"Ctrl+LMB: Pecah Segmen.\n" +"RMB: Hapus Titik." #: editor/plugins/abstract_polygon_2d_editor.cpp -#, fuzzy msgid "Delete points" -msgstr "Hapus" +msgstr "Hapus Titik" #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Toggle Autoplay" -msgstr "" +msgstr "Kondisikan Putar Otomatis" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Animation Name:" -msgstr "" +msgstr "Nama Animasi Baru:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Anim" -msgstr "" +msgstr "Animasi Baru" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Animation Name:" -msgstr "" +msgstr "Ubah Nama Animasi:" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Delete Animation?" -msgstr "Optimalkan Animasi" +msgstr "Hapus Animasi?" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Remove Animation" -msgstr "" +msgstr "Hapus Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: Invalid animation name!" -msgstr "" +msgstr "KESALAHAN: Nama animasi tidak valid!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: Animation name already exists!" -msgstr "" +msgstr "KESALAHAN: Nama animasi sudah ada!" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Rename Animation" -msgstr "" +msgstr "Ubah Nama Animasi" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Animation" -msgstr "" +msgstr "Tambah Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Next Changed" @@ -3081,95 +2987,106 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load Animation" -msgstr "" +msgstr "Muat Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Duplicate Animation" -msgstr "" +msgstr "Gandakan Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: No animation to copy!" -msgstr "" +msgstr "KESALAHAN: Tidak ada animasi untuk disalin!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "ERROR: No animation resource on clipboard!" -msgstr "" +msgstr "KESALAHAN: Tidak ada aset animasi di clipboard!" #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Pasted Animation" -msgstr "" +msgstr "Animasi Ditempel" #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Paste Animation" -msgstr "" +msgstr "Tempelkan Animasi" #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "ERROR: No animation to edit!" -msgstr "" +msgstr "KESALAHAN: Tidak ada animasi untuk disunting!" #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Play selected animation backwards from current pos. (A)" -msgstr "" +msgstr "Mainkan mundur animasi terpilih dari lokasi sekarang. (A)" #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Play selected animation backwards from end. (Shift+A)" -msgstr "" +msgstr "Mainkan mundur animasi terpilih dari akhir. (Shift+A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Stop animation playback. (S)" -msgstr "" +msgstr "Hentikan playback animasi. (S)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from start. (Shift+D)" -msgstr "" +msgstr "Mainkan animasi terpilih dari awal. (Shift+D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" -msgstr "" +msgstr "Mainkan animasi terpilih dari posisi sekarang. (D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." -msgstr "" +msgstr "Posisi Animasi (dalam detik)." #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Scale animation playback globally for the node." -msgstr "" +msgstr "Skalakan playback animasi secara global untuk node ini." #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Create new animation in player." -msgstr "" +msgstr "Buat animasi baru dalam pemutar animasi." #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Load animation from disk." -msgstr "" +msgstr "Memuat animasi dari diska." #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Load an animation from disk." -msgstr "" +msgstr "Memuat animasi dari diska." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Save the current animation" -msgstr "" +msgstr "Simpan animasi saat ini" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." -msgstr "" +msgstr "Tampilkan daftar animasi dalam pemutar animasi." #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Autoplay on Load" -msgstr "" +msgstr "Putar Otomatis saat Dimuat" #: editor/plugins/animation_player_editor_plugin.cpp +#, fuzzy msgid "Edit Target Blend Times" -msgstr "" +msgstr "Sunting Target Waktu Blend" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Tools" -msgstr "" +msgstr "Perkakas Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Copy Animation" -msgstr "" +msgstr "Salin Animasi" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Onion Skinning" @@ -3199,19 +3116,19 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "1 step" -msgstr "" +msgstr "1 langkah" #: editor/plugins/animation_player_editor_plugin.cpp msgid "2 steps" -msgstr "" +msgstr "2 langkah" #: editor/plugins/animation_player_editor_plugin.cpp msgid "3 steps" -msgstr "" +msgstr "3 langkah" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Differences Only" -msgstr "" +msgstr "Hanya yang berbeda" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Force White Modulate" @@ -3223,18 +3140,18 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" -msgstr "" +msgstr "Buat Animasi Baru" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Name:" -msgstr "" +msgstr "Nama Animasi:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp #: editor/script_create_dialog.cpp msgid "Error!" -msgstr "" +msgstr "Kesalahan!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Times:" @@ -3255,12 +3172,12 @@ msgstr "Animasi" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "New name:" -msgstr "" +msgstr "Nama baru:" #: editor/plugins/animation_tree_editor_plugin.cpp #, fuzzy msgid "Edit Filters" -msgstr "File:" +msgstr "Sunting Filter" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/multimesh_editor_plugin.cpp @@ -3389,8 +3306,9 @@ msgid "Import Animations.." msgstr "" #: editor/plugins/animation_tree_editor_plugin.cpp +#, fuzzy msgid "Edit Node Filters" -msgstr "" +msgstr "Sunting Filter Node" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Filters.." @@ -3420,27 +3338,26 @@ msgid "Can't resolve hostname:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Connection error, please try again." -msgstr "Gangguan koneks, silakan coba lagi." +msgstr "Gangguan koneksi, silakan coba lagi." #: editor/plugins/asset_library_editor_plugin.cpp #, fuzzy msgid "Can't connect to host:" -msgstr "Sambungkan Ke Node:" +msgstr "Tidak bisa terhubung ke host:" #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "No response from host:" -msgstr "" +msgstr "Tidak ada respon dari host:" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Request failed, return code:" -msgstr "Format file yang diminta tidak diketahui:" +msgstr "Permintaan gagal, return code:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, too many redirects" -msgstr "" +msgstr "Permintaan gagal, terlalu banyak pengalihan" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Bad download hash, assuming file has been tampered with." @@ -3455,12 +3372,13 @@ msgid "Got:" msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp +#, fuzzy msgid "Failed sha256 hash check" -msgstr "" +msgstr "Gagal mengecek hash sha256" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Asset Download Error:" -msgstr "" +msgstr "Gagal Mengunduh Aset:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Fetching:" @@ -3471,9 +3389,8 @@ msgid "Resolving.." msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Error making request" -msgstr "Error menyimpan resource!" +msgstr "Kesalahan saat melakukan permintaan" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Idle" @@ -3485,27 +3402,27 @@ msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download Error" -msgstr "" +msgstr "Unduhan Gagal" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download for this asset is already in progress!" -msgstr "" +msgstr "Unduhan untuk aset ini sedang diproses!" #: editor/plugins/asset_library_editor_plugin.cpp msgid "first" -msgstr "" +msgstr "pertama" #: editor/plugins/asset_library_editor_plugin.cpp msgid "prev" -msgstr "" +msgstr "sebelumnya" #: editor/plugins/asset_library_editor_plugin.cpp msgid "next" -msgstr "" +msgstr "selanjutnya" #: editor/plugins/asset_library_editor_plugin.cpp msgid "last" -msgstr "" +msgstr "terakhir" #: editor/plugins/asset_library_editor_plugin.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -3515,7 +3432,7 @@ msgstr "Semua" #: editor/plugins/asset_library_editor_plugin.cpp #: editor/project_settings_editor.cpp msgid "Plugins" -msgstr "" +msgstr "Pengaya" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Sort:" @@ -3548,14 +3465,18 @@ msgstr "Menguji" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" -msgstr "Aset-aset File ZIP" +msgstr "Berkas Aset ZIP" #: editor/plugins/baked_lightmap_editor_plugin.cpp +#, fuzzy msgid "" "Can't determine a save path for lightmap images.\n" "Save your scene (for images to be saved in the same dir), or pick a save " "path from the BakedLightmap properties." msgstr "" +"Tidak dapat menentukan lokasi penyimpanan untuk gambar lightmap\n" +"Simpan scene-mu (untuk gambar silakan simpan di direktori yang sama dengan " +"scene), atau tentukan lokasi penyimpanan dari properti BakedLightmap" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -3575,11 +3496,11 @@ msgstr "Ganti Radius Lampu" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Preview" -msgstr "" +msgstr "Pratinjau" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap" -msgstr "" +msgstr "Atur Snap" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -3640,12 +3561,14 @@ msgid "Create new horizontal and vertical guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp +#, fuzzy msgid "Edit IK Chain" -msgstr "" +msgstr "Sunting Rantai IK" #: editor/plugins/canvas_item_editor_plugin.cpp +#, fuzzy msgid "Edit CanvasItem" -msgstr "" +msgstr "Sunting CanvasItem" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -3812,15 +3735,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4006,8 +3929,9 @@ msgid "Toggle Curve Linear Tangent" msgstr "" #: editor/plugins/curve_editor_plugin.cpp +#, fuzzy msgid "Hold Shift to edit tangents individually" -msgstr "" +msgstr "Tahan Shift untuk menyunting tangen kurva satu-persatu" #: editor/plugins/gi_probe_editor_plugin.cpp msgid "Bake GI Probe" @@ -4031,8 +3955,9 @@ msgid "Items" msgstr "" #: editor/plugins/item_list_editor_plugin.cpp +#, fuzzy msgid "Item List Editor" -msgstr "" +msgstr "Penyunting Daftar Item" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "" @@ -4049,8 +3974,9 @@ msgid "Create a new polygon from scratch." msgstr "" #: editor/plugins/light_occluder_2d_editor_plugin.cpp +#, fuzzy msgid "Edit existing polygon:" -msgstr "" +msgstr "Sunting poligon yang ada:" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "LMB: Move Point." @@ -4572,8 +4498,9 @@ msgid "Transform UV Map" msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp +#, fuzzy msgid "Polygon 2D UV Editor" -msgstr "" +msgstr "Penyunting UV Poligon 2D" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Move Point" @@ -4609,7 +4536,7 @@ msgstr "" #: editor/project_settings_editor.cpp editor/property_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Edit" -msgstr "Edit" +msgstr "Sunting" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon->UV" @@ -4658,6 +4585,23 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +#, fuzzy +msgid "Open in Editor" +msgstr "Buka dalam Penyunting" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4837,7 +4781,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp #, fuzzy msgid "Debug with external editor" -msgstr "Editor Ketergantungan" +msgstr "Debug menggunakan penyunting eksternal" #: editor/plugins/script_editor_plugin.cpp msgid "Open Godot online documentation" @@ -4853,11 +4797,12 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "Go to previous edited document." -msgstr "" +msgstr "Ke dokumen yang disunting sebelumnya." #: editor/plugins/script_editor_plugin.cpp +#, fuzzy msgid "Go to next edited document." -msgstr "" +msgstr "Ke dokumen yang disunting selanjutnya." #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -4889,7 +4834,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp msgid "" "Built-in scripts can only be edited when the scene they belong to is loaded" -msgstr "" +msgstr "Skrip built-in hanya bisa disunting ketika scene induknya dimuat" #: editor/plugins/script_text_editor.cpp msgid "Only resources from filesystem can be dropped." @@ -4949,10 +4894,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "Pergi ke Baris" @@ -4966,6 +4907,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5717,8 +5662,9 @@ msgid "Texture Region" msgstr "" #: editor/plugins/texture_region_editor_plugin.cpp +#, fuzzy msgid "Texture Region Editor" -msgstr "" +msgstr "Penyunting Daerah Tekstur" #: editor/plugins/theme_editor_plugin.cpp msgid "Can't save theme to file:" @@ -5749,11 +5695,11 @@ msgstr "Hapus" #: editor/plugins/theme_editor_plugin.cpp msgid "Edit theme.." -msgstr "" +msgstr "Sunting tema.." #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." -msgstr "" +msgstr "Menu untuk menyunting tema." #: editor/plugins/theme_editor_plugin.cpp msgid "Add Class Items" @@ -5768,12 +5714,14 @@ msgid "Create Empty Template" msgstr "" #: editor/plugins/theme_editor_plugin.cpp +#, fuzzy msgid "Create Empty Editor Template" -msgstr "" +msgstr "Buat Templat Penyunting Kosongan" #: editor/plugins/theme_editor_plugin.cpp +#, fuzzy msgid "Create From Current Editor Theme" -msgstr "" +msgstr "Buat dari Tema Editor Saat Ini" #: editor/plugins/theme_editor_plugin.cpp msgid "CheckBox Radio1" @@ -5823,11 +5771,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -6099,10 +6042,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -6124,12 +6063,14 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." -msgstr "" +msgstr "Tidak dapat menyunting project.godot dalam lokasi proyek." #: editor/project_manager.cpp msgid "Couldn't create project.godot in project path." @@ -6145,10 +6086,6 @@ msgid "Rename Project" msgstr "Projek Baru Permainan" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp #, fuzzy msgid "New Game Project" msgstr "Projek Baru Permainan" @@ -6158,27 +6095,24 @@ msgid "Import Existing Project" msgstr "Impor Projek yang Sudah Ada" #: editor/project_manager.cpp -#, fuzzy msgid "Import & Edit" -msgstr "Impor" +msgstr "Impor & Ubah" #: editor/project_manager.cpp msgid "Create New Project" msgstr "Buat Projek Baru" #: editor/project_manager.cpp -#, fuzzy msgid "Create & Edit" -msgstr "Buat" +msgstr "Buat & Ubah" #: editor/project_manager.cpp msgid "Install Project:" msgstr "" #: editor/project_manager.cpp -#, fuzzy msgid "Install & Edit" -msgstr "Pasang" +msgstr "Pasang & Ubah" #: editor/project_manager.cpp msgid "Project Name:" @@ -6869,10 +6803,6 @@ msgstr "Resource" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6987,10 +6917,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "Buka Cepat Script.." @@ -7436,33 +7362,47 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "Hapus yang Dipilih" +msgid "Next Plane" +msgstr "Tab selanjutnya" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "Duplikat Pilihan" +msgid "Previous Plane" +msgstr "Tab sebelumnya" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +#, fuzzy +msgid "Previous Floor" +msgstr "Tab sebelumnya" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Previous Floor" -msgstr "Tab sebelumnya" +msgid "GridMap Delete Selection" +msgstr "Hapus yang Dipilih" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Duplicate Selection" +msgstr "Duplikat Pilihan" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7576,6 +7516,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "Buat Subskribsi" @@ -7593,6 +7537,10 @@ msgstr "Proyek" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -8162,6 +8110,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8358,6 +8314,17 @@ msgstr "Error memuat font." msgid "Invalid font size." msgstr "Ukuran font tidak sah." +#, fuzzy +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Format version.txt tidak valid dalam berkas templat. Revisi tidak valid." + +#, fuzzy +#~ msgid "Can't write file." +#~ msgstr "Tidak dapat membuat folder." + #~ msgid "Next" #~ msgstr "Berikutnya" diff --git a/editor/translations/is.po b/editor/translations/is.po index 3cccf15a6c..b0b8698f37 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -2365,12 +2365,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2423,10 +2417,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3590,15 +3580,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4421,6 +4411,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4703,10 +4709,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "" @@ -4719,6 +4721,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5559,11 +5565,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5823,10 +5824,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5847,7 +5844,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5867,10 +5866,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6558,10 +6553,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6671,10 +6662,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7097,11 +7084,23 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +msgid "Next Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7109,19 +7108,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7229,6 +7228,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7244,6 +7247,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7743,6 +7750,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/editor/translations/it.po b/editor/translations/it.po index 86700a094b..ba1a09e3ad 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -2485,14 +2485,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Formato di version.txt invalido nelle templates." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Formato di version.txt invalido nelle templates. Revision non é un " -"identificatore valido." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Non é stato trovato version.txt all'interno di templates." @@ -2549,10 +2541,6 @@ msgid "Failed:" msgstr "Fallito:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Impossibile scrivere il file." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Download Completato." @@ -3756,16 +3744,16 @@ msgstr "Mostra Griglia" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy -msgid "Show helpers" +msgid "Show Helpers" msgstr "Mostra Ossa" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy -msgid "Show rulers" +msgid "Show Rulers" msgstr "Mostra Ossa" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Mostra guide" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4624,6 +4612,22 @@ msgid "Resource clipboard is empty!" msgstr "Clipboard risorse vuota!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Apri nell Editor" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Istanza:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Tipo:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Carica Risorsa" @@ -4923,10 +4927,6 @@ msgid "Toggle Comment" msgstr "Cambia a Commento" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Clona Sotto" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "Svolgere Linea" @@ -4941,6 +4941,10 @@ msgid "Unfold All Lines" msgstr "Svolgere Tutte le Linee" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Clona Sotto" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "Completa Simbolo" @@ -5799,11 +5803,6 @@ msgstr "Tab 2" msgid "Tab 3" msgstr "Tab 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Tipo:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Tipo Dato:" @@ -6082,11 +6081,6 @@ msgid "Please choose an empty folder." msgstr "Si prega di esportare al di fuori della cartella del progetto!" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" -"Per favore seleziona una cartella che non contiene un file 'project.godot'." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Progetto Importato" @@ -6109,7 +6103,9 @@ msgstr "Percorso di progetto invalido (cambiato qualcosa?)." #: editor/project_manager.cpp #, fuzzy -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "Impossibile creare project.godot nel percorso di progetto." #: editor/project_manager.cpp @@ -6131,11 +6127,6 @@ msgid "Rename Project" msgstr "Progetto Senza Nome" #: editor/project_manager.cpp -#, fuzzy -msgid "Couldn't get project.godot in the project path." -msgstr "Impossibile creare project.godot nel percorso di progetto." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Nuovo Progetto di Gioco" @@ -6866,10 +6857,6 @@ msgstr "Sub-Risorse:" msgid "Clear Inheritance" msgstr "Liberare ereditarietà " -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Apri nell Editor" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Elimina Nodo(i)" @@ -6991,10 +6978,6 @@ msgstr "" "Fai click per mostrare il dock gruppi." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "Istanza:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Apri script" @@ -7436,13 +7419,26 @@ msgstr "L'oggetto non può fornire una lunghezza." #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "Elimina selezionati" +msgid "Next Plane" +msgstr "Scheda successiva" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "Duplica Selezione" +msgid "Previous Plane" +msgstr "Scheda precedente" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "Prossimo Piano" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "Previous Floor" +msgstr "Scheda precedente" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" @@ -7450,22 +7446,23 @@ msgstr "Piano:" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Grid Map" -msgstr "Snap Griglia" +msgid "GridMap Delete Selection" +msgstr "Elimina selezionati" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Snap View" -msgstr "Vista dall'Alto" +msgid "GridMap Duplicate Selection" +msgstr "Duplica Selezione" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Previous Floor" -msgstr "Scheda precedente" +msgid "Grid Map" +msgstr "Snap Griglia" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "Prossimo Piano" +#, fuzzy +msgid "Snap View" +msgstr "Vista dall'Alto" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy @@ -7593,6 +7590,10 @@ msgid "Mono" msgstr "Mono" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "Crea Outline" @@ -7612,6 +7613,10 @@ msgstr "Progetto" msgid "Warnings" msgstr "Avvertimento" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -8194,6 +8199,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin necessita di un nodo figlio ARVRCamera" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp #, fuzzy msgid "Plotting Meshes: " msgstr "Bliting Immagini" @@ -8399,6 +8412,29 @@ msgstr "Errore caricamento font." msgid "Invalid font size." msgstr "Dimensione font Invalida." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Formato di version.txt invalido nelle templates. Revision non é un " +#~ "identificatore valido." + +#~ msgid "Can't write file." +#~ msgstr "Impossibile scrivere il file." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "" +#~ "Per favore seleziona una cartella che non contiene un file 'project." +#~ "godot'." + +#, fuzzy +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "Impossibile creare project.godot nel percorso di progetto." + +#, fuzzy +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "Impossibile creare project.godot nel percorso di progetto." + #~ msgid "Next" #~ msgstr "Successivo" diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 061a3909e9..905c498a3c 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -2746,14 +2746,6 @@ msgid "Invalid version.txt format inside templates." msgstr "テンプレート内ã®version.txt フォーマットãŒä¸æ£ã§ã™." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"テンプレート内ã®version.txt フォーマットãŒä¸æ£ã§ã™. Revisionã¯æœ‰åŠ¹ãªè˜åˆ¥åã§" -"ã¯ã‚ã‚Šã¾ã›ã‚“." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "テンプレート内ã«version.txtãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“." @@ -2814,10 +2806,6 @@ msgid "Failed:" msgstr "失敗:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "ファイルã«æ›¸ãè¾¼ã¿ã§ãã¾ã›ã‚“ã§ã—ãŸ." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "ダウンãƒãƒ¼ãƒ‰å®Œäº†." @@ -4145,17 +4133,17 @@ msgstr "グリッドを表示" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy -msgid "Show helpers" +msgid "Show Helpers" msgstr "ボーンを表示ã™ã‚‹" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy -msgid "Show rulers" +msgid "Show Rulers" msgstr "ボーンを表示ã™ã‚‹" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy -msgid "Show guides" +msgid "Show Guides" msgstr "ボーンを表示ã™ã‚‹" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -5106,6 +5094,23 @@ msgid "Resource clipboard is empty!" msgstr "リソースã®ã‚¯ãƒªãƒƒãƒ—ボードã¯ç©ºã§ã™!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "エディタã§é–‹ã" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "インスタンス:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +#, fuzzy +msgid "Type:" +msgstr "åž‹(Type):" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "リソースをèªã¿è¾¼ã‚€" @@ -5418,11 +5423,6 @@ msgstr "コメントを切り替ãˆã‚‹" #: editor/plugins/script_text_editor.cpp #, fuzzy -msgid "Clone Down" -msgstr "複製ã—ã¦ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰" - -#: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Fold/Unfold Line" msgstr "è¡Œã«ç§»å‹•" @@ -5436,6 +5436,11 @@ msgstr "" #: editor/plugins/script_text_editor.cpp #, fuzzy +msgid "Clone Down" +msgstr "複製ã—ã¦ãƒ€ã‚¦ãƒ³ãƒãƒ¼ãƒ‰" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy msgid "Complete Symbol" msgstr "記å·ã™ã¹ã¦" @@ -6344,12 +6349,6 @@ msgstr "タブ2" msgid "Tab 3" msgstr "タブ3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -#, fuzzy -msgid "Type:" -msgstr "åž‹(Type):" - #: editor/plugins/theme_editor_plugin.cpp #, fuzzy msgid "Data Type:" @@ -6643,10 +6642,6 @@ msgid "Please choose an empty folder." msgstr "'project.godot' ファイルをé¸æŠžã—ã¦ãã ã•ã„." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "'project.godot'ãŒãªã„フォルダをé¸æŠžã—ã¦ãã ã•ã„." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "インãƒãƒ¼ãƒˆã•ã‚ŒãŸãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆ" @@ -6670,7 +6665,9 @@ msgstr "ä¸æ£ãªãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆã®ãƒ‘ス(何ã‹å¤‰ãˆã¾ã—ãŸã‹ï¼Ÿï¼‰" #: editor/project_manager.cpp #, fuzzy -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "project.godotをプãƒã‚¸ã‚§ã‚¯ãƒˆãƒ‘スã«ç”Ÿæˆã§ãã¾ã›ã‚“ã§ã—ãŸ" #: editor/project_manager.cpp @@ -6694,11 +6691,6 @@ msgid "Rename Project" msgstr "åç„¡ã—ã®ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆ" #: editor/project_manager.cpp -#, fuzzy -msgid "Couldn't get project.godot in the project path." -msgstr "project.godotをプãƒã‚¸ã‚§ã‚¯ãƒˆãƒ‘スã«ç”Ÿæˆã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "æ–°ã—ã„ゲームプãƒã‚¸ã‚§ã‚¯ãƒˆ" @@ -7471,10 +7463,6 @@ msgstr "サブリソース:" msgid "Clear Inheritance" msgstr "継承をクリアã™ã‚‹" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "エディタã§é–‹ã" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "ノードを消去" @@ -7610,10 +7598,6 @@ msgstr "" "クリックã—ã¦ã‚°ãƒ«ãƒ¼ãƒ—ã®ãƒ‰ãƒƒã‚¯ã‚’表示ã—ã¦ãã ã•ã„." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "インスタンス:" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "フォルダを作æˆ" @@ -8080,13 +8064,25 @@ msgstr "オブジェクトã«é•·ã•ãŒã‚ã‚Šã¾ã›ã‚“." #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "é¸æŠžç¯„囲を消去" +msgid "Next Plane" +msgstr "次ã®ã‚¿ãƒ–" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "é¸æŠžç¯„囲を複製" +msgid "Previous Plane" +msgstr "以å‰ã®ã‚¿ãƒ–" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "次ã®åºŠé¢" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "å‰ã®åºŠé¢" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" @@ -8094,21 +8090,23 @@ msgstr "床é¢:" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Grid Map" -msgstr "グリッドSnap" +msgid "GridMap Delete Selection" +msgstr "é¸æŠžç¯„囲を消去" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Snap View" -msgstr "上é¢å›³" +msgid "GridMap Duplicate Selection" +msgstr "é¸æŠžç¯„囲を複製" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "å‰ã®åºŠé¢" +#, fuzzy +msgid "Grid Map" +msgstr "グリッドSnap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "次ã®åºŠé¢" +#, fuzzy +msgid "Snap View" +msgstr "上é¢å›³" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy @@ -8230,6 +8228,10 @@ msgid "Mono" msgstr "モノラル音声" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "アウトラインを生æˆ" @@ -8248,6 +8250,10 @@ msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆ" msgid "Warnings" msgstr "è¦å‘Š" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp #, fuzzy msgid "" @@ -8865,6 +8871,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROriginã¯ARVRCameraåノードãŒå¿…è¦ã§ã™" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp #, fuzzy msgid "Plotting Meshes: " msgstr "イメージをé…ç½®(Blit)" @@ -9070,6 +9084,27 @@ msgstr "フォントèªã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã€‚" msgid "Invalid font size." msgstr "無効ãªãƒ•ã‚©ãƒ³ãƒˆ サイズã§ã™ã€‚" +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "テンプレート内ã®version.txt フォーマットãŒä¸æ£ã§ã™. Revisionã¯æœ‰åŠ¹ãªè˜åˆ¥å" +#~ "ã§ã¯ã‚ã‚Šã¾ã›ã‚“." + +#~ msgid "Can't write file." +#~ msgstr "ファイルã«æ›¸ãè¾¼ã¿ã§ãã¾ã›ã‚“ã§ã—ãŸ." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "'project.godot'ãŒãªã„フォルダをé¸æŠžã—ã¦ãã ã•ã„." + +#, fuzzy +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "project.godotをプãƒã‚¸ã‚§ã‚¯ãƒˆãƒ‘スã«ç”Ÿæˆã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#, fuzzy +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "project.godotをプãƒã‚¸ã‚§ã‚¯ãƒˆãƒ‘スã«ç”Ÿæˆã§ãã¾ã›ã‚“ã§ã—ãŸ" + #~ msgid "Next" #~ msgstr "次" diff --git a/editor/translations/ko.po b/editor/translations/ko.po index 29518c9797..28294c7307 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -7,13 +7,14 @@ # Ch <ccwpc@hanmail.net>, 2017. # paijai 송 (fivejobi) <xotjq237@gmail.com>, 2018. # TheRedPlanet <junmo.moon8@gmail.com>, 2018. +# Xavier Cho <mysticfallband@gmail.com>, 2018. # msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-01-20 17:48+0000\n" -"Last-Translator: 박한얼 <volzhs@gmail.com>\n" +"PO-Revision-Date: 2018-02-24 08:39+0000\n" +"Last-Translator: TheRedPlanet <junmo.moon8@gmail.com>\n" "Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/" "godot/ko/>\n" "Language: ko\n" @@ -21,7 +22,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -36,8 +37,9 @@ msgid "Anim Change Keyframe Time" msgstr "ì• ë‹ˆë©”ì´ì…˜ í‚¤í”„ë ˆìž„ 시간 변경" #: editor/animation_editor.cpp +#, fuzzy msgid "Anim Change Transition" -msgstr "ì• ë‹ˆë©”ì´ì…˜ 변화 변경" +msgstr "ì• ë‹ˆë©”ì´ì…˜ êµì²´ 트랜지션" #: editor/animation_editor.cpp msgid "Anim Change Transform" @@ -162,8 +164,9 @@ msgid "Constant" msgstr "ë¹„ì„ í˜•" #: editor/animation_editor.cpp +#, fuzzy msgid "In" -msgstr "안" +msgstr "In" #: editor/animation_editor.cpp msgid "Out" @@ -2098,7 +2101,7 @@ msgstr "프로ì 트 실행." #: editor/editor_node.cpp msgid "Play" -msgstr "재성" +msgstr "실행" #: editor/editor_node.cpp msgid "Pause the scene" @@ -2443,14 +2446,6 @@ msgid "Invalid version.txt format inside templates." msgstr "템플릿 ì•ˆì— version.txtê°€ ìœ íš¨í•˜ì§€ ì•Šì€ í˜•ì‹ìž…니다." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"í…œí”Œë¦¿ì— version.txt 형ì‹ì´ ìœ íš¨í•˜ì§€ 않습니다. ë¦¬ë¹„ì „ì€ ìœ íš¨í•œ ì‹ë³„ìžê°€ ì•„ë‹™" -"니다." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "í…œí”Œë¦¿ì— version.txt를 ì°¾ì„ ìˆ˜ 없습니다." @@ -2505,10 +2500,6 @@ msgid "Failed:" msgstr "실패:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "파ì¼ì— 쓸 수 없습니다." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "다운로드 완료." @@ -3686,15 +3677,15 @@ msgid "Show Grid" msgstr "그리드 보기" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "í—¬í¼ ë³´ê¸°" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "ìž ë³´ê¸°" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "ê°€ì´ë“œ 보기" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4521,6 +4512,22 @@ msgid "Resource clipboard is empty!" msgstr "리소스 í´ë¦½ë³´ë“œê°€ 비었습니다!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "ì—디터ì—ì„œ 열기" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "ì¸ìŠ¤í„´ìŠ¤:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "타입:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "리소스 로드" @@ -4805,10 +4812,6 @@ msgid "Toggle Comment" msgstr "ì£¼ì„ í† ê¸€" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "아래로 ë³µì œ" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "ë¼ì¸ 펼치기/ì ‘ê¸°" @@ -4821,6 +4824,10 @@ msgid "Unfold All Lines" msgstr "ëª¨ë“ ë¼ì¸ 펼치기" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "아래로 ë³µì œ" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "ìžë™ 완성" @@ -5664,11 +5671,6 @@ msgstr "íƒ 2" msgid "Tab 3" msgstr "íƒ 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "타입:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "ë°ì´íƒ€ 타입:" @@ -5932,10 +5934,6 @@ msgid "Please choose an empty folder." msgstr "비어있는 í´ë”를 ì„ íƒí•˜ì„¸ìš”." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "'project.godot' 파ì¼ì´ 없는 í´ë”를 ì„ íƒ í•˜ì‹ì‹œì˜¤." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "ê°€ì ¸ì˜¨ 프로ì 트" @@ -5956,8 +5954,12 @@ msgid "Invalid project path (changed anything?)." msgstr "ìœ íš¨í•˜ì§€ ì•Šì€ í”„ë¡œì 트 경로 (ë”ê°€ ë³€ê²½í•˜ì‹ ê±°ë¼ë„?)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "프로ì 트 ê²½ë¡œì— project.godot 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" +"프로ì 트 경로로 부터 project.godot 파ì¼ì„ 로드 í• ìˆ˜ 없습니다 (ì—러 %d). 존재" +"하지 않거나 ì†ìƒë˜ì—ˆì„ 수 있습니다." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -5976,10 +5978,6 @@ msgid "Rename Project" msgstr "프로ì 트 ì´ë¦„ 변경" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "프로ì 트 ê²½ë¡œì— project.godot 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "새 게임 프로ì 트" @@ -6678,10 +6676,6 @@ msgstr "서브-리소스" msgid "Clear Inheritance" msgstr "ìƒì† 지우기" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "ì—디터ì—ì„œ 열기" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "노드 ì‚ì œ" @@ -6798,10 +6792,6 @@ msgstr "" "í´ë¦í•´ì„œ 그룹 ë…ì„ ë³´ì‹ì‹œì˜¤." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "ì¸ìŠ¤í„´ìŠ¤:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "스í¬ë¦½íŠ¸ 열기" @@ -7231,32 +7221,44 @@ msgid "Object can't provide a length." msgstr "오브ì 트는 길ì´ë¥¼ ì œê³µí• ìˆ˜ 없습니다." #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "그리드맵 ì„ íƒ ì‚ì œ" +msgid "Next Plane" +msgstr "ë‹¤ìŒ í‰ë©´" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "그리드맵 ì„ íƒ ë³µì œ" +msgid "Previous Plane" +msgstr "ì´ì „ í‰ë©´" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "í‰ë©´:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "ë‹¤ìŒ ì¸µ" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "ì´ì „ 층" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "층:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "그리드맵" +msgid "GridMap Delete Selection" +msgstr "그리드맵 ì„ íƒ ì‚ì œ" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "스냅 ë·°" +msgid "GridMap Duplicate Selection" +msgstr "그리드맵 ì„ íƒ ë³µì œ" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "ì´ì „ 층" +msgid "Grid Map" +msgstr "그리드맵" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "ë‹¤ìŒ ì¸µ" +msgid "Snap View" +msgstr "스냅 ë·°" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7363,6 +7365,10 @@ msgid "Mono" msgstr "모노" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "C# 지ì›ì— 대하여" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "C# 솔루션 만들기" @@ -7378,6 +7384,10 @@ msgstr "프로ì 트 빌드" msgid "Warnings" msgstr "ê²½ê³ " +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7919,6 +7929,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROriginì€ ARVRCamera ìžì‹ 노드를 요구 함" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "%d%%" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "(ë‚¨ì€ ì‹œê°„: %d:%02d s)" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "메시 구분 중: " @@ -8114,6 +8132,25 @@ msgstr "í°íŠ¸ 로딩 ì—러." msgid "Invalid font size." msgstr "ìœ íš¨í•˜ì§€ ì•Šì€ í°íŠ¸ í¬ê¸°." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "í…œí”Œë¦¿ì— version.txt 형ì‹ì´ ìœ íš¨í•˜ì§€ 않습니다. ë¦¬ë¹„ì „ì€ ìœ íš¨í•œ ì‹ë³„ìžê°€ ì•„" +#~ "닙니다." + +#~ msgid "Can't write file." +#~ msgstr "파ì¼ì— 쓸 수 없습니다." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "'project.godot' 파ì¼ì´ 없는 í´ë”를 ì„ íƒ í•˜ì‹ì‹œì˜¤." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "프로ì 트 ê²½ë¡œì— project.godot 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "프로ì 트 ê²½ë¡œì— project.godot 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다." + #~ msgid "Next" #~ msgstr "다ìŒ" diff --git a/editor/translations/lt.po b/editor/translations/lt.po index 5e5400d1e7..0ad2945bdc 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -2374,12 +2374,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Å ablonuose nerasta version.txt failo." @@ -2433,10 +2427,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3608,15 +3598,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4439,6 +4429,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4721,10 +4727,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "" @@ -4737,6 +4739,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5578,11 +5584,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5842,10 +5843,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5866,7 +5863,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5886,10 +5885,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6580,10 +6575,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6693,10 +6684,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7119,11 +7106,23 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +msgid "Next Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7131,19 +7130,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7251,6 +7250,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7266,6 +7269,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7765,6 +7772,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/editor/translations/nb.po b/editor/translations/nb.po index 623898fcb5..8d9ffe7a21 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -2477,13 +2477,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Ugyldig version.txt format i mal." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Ugyldig version.txt format i mal. Revisjon er ikke en gyldig identifikator." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Ingen version.txt funnet i mal." @@ -2542,10 +2535,6 @@ msgid "Failed:" msgstr "Feilet:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Kan ikke skrive fil." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Nedlastning fullført." @@ -3758,15 +3747,15 @@ msgid "Show Grid" msgstr "Vis Rutenett" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Vis hjelpere" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Vis linjaler" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Vis veiledere" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4602,6 +4591,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4891,10 +4896,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "Slett Valgte" @@ -4908,6 +4909,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5754,11 +5759,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -6021,10 +6021,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -6046,7 +6042,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -6066,10 +6064,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6766,10 +6760,6 @@ msgstr "Ressurs" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6882,10 +6872,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7313,32 +7299,46 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "Slett Valgte" +msgid "Next Plane" +msgstr "Neste fane" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "Dupliser Utvalg" +msgid "Previous Plane" +msgstr "Forrige fane" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Delete Selection" +msgstr "Slett Valgte" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "GridMap Duplicate Selection" +msgstr "Dupliser Utvalg" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7453,6 +7453,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "Lag Omriss" @@ -7470,6 +7474,10 @@ msgstr "Prosjekt" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7991,6 +7999,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8153,6 +8169,16 @@ msgstr "" msgid "Invalid font size." msgstr "Ugyldig fontstørrelse." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Ugyldig version.txt format i mal. Revisjon er ikke en gyldig " +#~ "identifikator." + +#~ msgid "Can't write file." +#~ msgstr "Kan ikke skrive fil." + #~ msgid "Next" #~ msgstr "Neste" diff --git a/editor/translations/nl.po b/editor/translations/nl.po index c44ef3ebc8..e54a0c7960 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -5,24 +5,26 @@ # # aelspire <aelspire@gmail.com>, 2017. # Aram Nap <xyphex.aram@gmail.com>, 2017. -# Arjan219 <arjannugteren1@gmail.com>, 2017. +# Arjan219 <arjannugteren1@gmail.com>, 2017-2018. # Christophe Swolfs <swolfschristophe@gmail.com>, 2017. # Cornee Traas <corneetraas@hotmail.com>, 2017. # Daeran Wereld <daeran@gmail.com>, 2017. # Dzejkop <jakubtrad@gmail.com>, 2017. # Ferdinand de Coninck <ferdinand.deconinck@gmail.com>, 2018. +# Jorn Theunissen <jorn-theunissen@hotmail.com>, 2018. # Maikel <maikel_martens_1@hotmail.com>, 2017. # Pieter-Jan Briers <pieterjan.briers@gmail.com>, 2017-2018. # Robin Arys <robinarys@hotmail.com>, 2017. # Senno Kaasjager <senno.kaasjager@gmail.com>, 2017. # Uxilo <jmolendijk93@gmail.com>, 2017-2018. +# Willem <studiebolmail@gmail.com>, 2018. # Wout Standaert <wout@blobkat.com>, 2017. # Zatherz <zatherz@linux.pl>, 2017. # msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-01-22 08:07+0000\n" +"PO-Revision-Date: 2018-02-17 19:35+0000\n" "Last-Translator: Pieter-Jan Briers <pieterjan.briers@gmail.com>\n" "Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/" "nl/>\n" @@ -30,7 +32,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.19\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -1693,7 +1695,6 @@ msgid "Export Mesh Library" msgstr "Exporteer Mesh Library" #: editor/editor_node.cpp -#, fuzzy msgid "This operation can't be done without a root node." msgstr "Deze bewerking is niet mogelijk zonder een hoofdknoop." @@ -2065,7 +2066,6 @@ msgstr "" "efficiënter met het netwerk bestandssysteem." #: editor/editor_node.cpp -#, fuzzy msgid "Editor" msgstr "Editor" @@ -2302,9 +2302,8 @@ msgid "Creating Mesh Previews" msgstr "Creëren van Mesh Previews" #: editor/editor_plugin.cpp -#, fuzzy msgid "Thumbnail.." -msgstr "Thumbnail.." +msgstr "Voorbeeld.." #: editor/editor_plugin_settings.cpp msgid "Installed Plugins:" @@ -2472,14 +2471,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Ongeldig version.txt formaat in sjablonen." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Ongeldig version.txt formaat in sjablonen. Revisie is geen geldig " -"identificatienummer." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Geen version.txt gevonden in sjablonen." @@ -2534,16 +2525,12 @@ msgid "Failed:" msgstr "Mislukt:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Kan niet naar bestand schrijven." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Download Voltooid." #: editor/export_template_manager.cpp msgid "Error requesting url: " -msgstr "Fout met het opvragen van url: " +msgstr "Fout bij het opvragen van een URL: " #: editor/export_template_manager.cpp msgid "Connecting to Mirror.." @@ -3225,7 +3212,7 @@ msgstr "Hoeveelheid:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend:" -msgstr "Mengen" +msgstr "Mengen:" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend 0:" @@ -3249,7 +3236,7 @@ msgstr "Voeg invoer toe" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Clear Auto-Advance" -msgstr "Verwijder Automatische Voortgang." +msgstr "Verwijder Automatische Voortgang" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Set Auto-Advance" @@ -3455,7 +3442,6 @@ msgid "Official" msgstr "Officieel" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Testing" msgstr "Testen" @@ -3738,15 +3724,15 @@ msgid "Show Grid" msgstr "Raster Weergeven" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Toon helpers" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Toon linialen" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Toon hulplijnen" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4035,11 +4021,11 @@ msgid "UV Unwrap failed, mesh may not be manifold?" msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp +#, fuzzy msgid "No mesh to debug." -msgstr "" +msgstr "Geen mesh om te debuggen." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Model has no UV in this layer" msgstr "Model heeft geen UV in deze laag" @@ -4048,7 +4034,6 @@ msgid "MeshInstance lacks a Mesh!" msgstr "MeshInstance ontbreekt een Mesh!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Mesh has not surface to create outlines from!" msgstr "Mesh heeft geen oppervlakte om omlijning van te maken!" @@ -4169,7 +4154,7 @@ msgstr "" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Populate MultiMesh" -msgstr "" +msgstr "Vul MultiMesh" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Target Surface:" @@ -4246,8 +4231,9 @@ msgid "Constructing compact heightfield..." msgstr "Compact hoogteveld aan het bouwen..." #: editor/plugins/navigation_mesh_generator.cpp +#, fuzzy msgid "Eroding walkable area..." -msgstr "" +msgstr "Wandelbaar gebied eroderen..." #: editor/plugins/navigation_mesh_generator.cpp msgid "Partitioning..." @@ -4292,11 +4278,11 @@ msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Error loading image:" -msgstr "" +msgstr "Error bij het laden van afbeelding:" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "No pixels with transparency > 128 in image.." -msgstr "" +msgstr "Geen pixels met transparantie > 128 in afbeelding.." #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generate Visibility Rect" @@ -4600,6 +4586,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4737,7 +4739,7 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp msgid "Run" -msgstr "" +msgstr "Starten" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -4890,10 +4892,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "Ga naar Regel" @@ -4907,6 +4905,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5764,11 +5766,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -6038,10 +6035,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -6063,7 +6056,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -6084,10 +6079,6 @@ msgid "Rename Project" msgstr "Hernoem Functie" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6102,7 +6093,7 @@ msgstr "Importeren" #: editor/project_manager.cpp msgid "Create New Project" -msgstr "" +msgstr "Creëer Nieuw Project" #: editor/project_manager.cpp #, fuzzy @@ -6199,7 +6190,7 @@ msgstr "" #: editor/project_manager.cpp msgid "New Project" -msgstr "" +msgstr "Nieuw Project" #: editor/project_manager.cpp #, fuzzy @@ -6791,10 +6782,6 @@ msgstr "Resource" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6907,10 +6894,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "Omschrijving:" @@ -7348,33 +7331,47 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "Geselecteerde Verwijderen" +msgid "Next Plane" +msgstr "Volgend tabblad" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "Dupliceer Selectie" +msgid "Previous Plane" +msgstr "Vorig tabblad" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +#, fuzzy +msgid "Previous Floor" +msgstr "Vorig tabblad" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Previous Floor" -msgstr "Vorig tabblad" +msgid "GridMap Delete Selection" +msgstr "Geselecteerde Verwijderen" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Duplicate Selection" +msgstr "Dupliceer Selectie" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7488,6 +7485,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "Subscriptie Maken" @@ -7505,6 +7506,10 @@ msgstr "Project" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -8073,6 +8078,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8262,6 +8275,16 @@ msgstr "Fout bij het laden van lettertype." msgid "Invalid font size." msgstr "Ongeldige lettertype grootte." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Ongeldig version.txt formaat in sjablonen. Revisie is geen geldig " +#~ "identificatienummer." + +#~ msgid "Can't write file." +#~ msgstr "Kan niet naar bestand schrijven." + #~ msgid "Next" #~ msgstr "Volgende" diff --git a/editor/translations/pl.po b/editor/translations/pl.po index f5b08d11c1..21618953a0 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -2463,14 +2463,6 @@ msgid "Invalid version.txt format inside templates." msgstr "NieprawidÅ‚owy format pliku version.txt w szablonach." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"nieprawidÅ‚owy format pliku version.txt wewnÄ…trz szablonów. Zmiana nie jest " -"prawidÅ‚owym identyfikatorem." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Nie znaleziono pliku version.txt w szablonach." @@ -2525,10 +2517,6 @@ msgid "Failed:" msgstr "Nie powiodÅ‚o siÄ™:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Nie można zapisać pliku." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Pobieranie zakoÅ„czone." @@ -3726,15 +3714,15 @@ msgid "Show Grid" msgstr "Pokaż siatkÄ™" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Pokaż linie pomocnicze" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Pokaż linijki" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Pokaż prowadnice" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4585,6 +4573,22 @@ msgid "Resource clipboard is empty!" msgstr "Schowka zasobów jest pusty!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Otwórz w edytorze" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Instancja:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Typ:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Wczytaj Zasób" @@ -4874,10 +4878,6 @@ msgid "Toggle Comment" msgstr "Ustaw komentarz" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Duplikuj liniÄ™" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "ZwiÅ„/rozwiÅ„ wiersz" @@ -4890,6 +4890,10 @@ msgid "Unfold All Lines" msgstr "RozwiÅ„ wszystkie linie" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Duplikuj liniÄ™" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "UzupeÅ‚nij symbol" @@ -5756,11 +5760,6 @@ msgstr "ZakÅ‚adka 2" msgid "Tab 3" msgstr "ZakÅ‚adka 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Typ:" - #: editor/plugins/theme_editor_plugin.cpp #, fuzzy msgid "Data Type:" @@ -6028,10 +6027,6 @@ msgid "Please choose an empty folder." msgstr "ProszÄ™ wybrać plik 'project.godot'." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "ProszÄ™ wybrać folder nie zawierajÄ…cy pliku 'project.godot'." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Zaimportowano projekt" @@ -6052,8 +6047,11 @@ msgid "Invalid project path (changed anything?)." msgstr "Niepoprawna Å›cieżka projektu (zmienić cokolwiek?)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "Nie można byÅ‚o utworzyć engine.cfg w Å›cieżce projektu." +#, fuzzy +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "Nie można byÅ‚o edytować engine.cfg w Å›cieżce projektu." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -6072,10 +6070,6 @@ msgid "Rename Project" msgstr "ZmieÅ„ nazwÄ™ projektu" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "Nie znaleziono project.godot w Å›cieżce projektu." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Nowy projekt gry" @@ -6781,10 +6775,6 @@ msgstr "Zasoby" msgid "Clear Inheritance" msgstr "Wyczyść dziedziczenie" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Otwórz w edytorze" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "UsuÅ„ wÄ™zeÅ‚ (wÄ™zÅ‚y)" @@ -6902,10 +6892,6 @@ msgstr "" "Kliknij, aby wyÅ›wietlić panel grup." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "Instancja:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Otwórz skrypt" @@ -7336,32 +7322,46 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "GridMap UsuÅ„ zaznaczenie" +#, fuzzy +msgid "Next Plane" +msgstr "NastÄ™pna zakÅ‚adka" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "GridMap duplikuj zaznaczenie" +#, fuzzy +msgid "Previous Plane" +msgstr "Poprzednia zakÅ‚adka" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "NastÄ™pny poziom" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Poprzedni poziom" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "Poziom:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "Grid Map" +msgid "GridMap Delete Selection" +msgstr "GridMap UsuÅ„ zaznaczenie" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "PrzyciÄ…ganie widoku" +msgid "GridMap Duplicate Selection" +msgstr "GridMap duplikuj zaznaczenie" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "Poprzedni poziom" +msgid "Grid Map" +msgstr "Grid Map" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "NastÄ™pny poziom" +msgid "Snap View" +msgstr "PrzyciÄ…ganie widoku" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy @@ -7475,6 +7475,10 @@ msgid "Mono" msgstr "Mono" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "Utwórz solucjÄ™ C#" @@ -7490,6 +7494,10 @@ msgstr "Zbuduj projekt" msgid "Warnings" msgstr "Ostrzeżenia" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -8029,6 +8037,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin wymaga by ARVRCamera dziedziczyÅ‚a po node" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8227,6 +8243,25 @@ msgstr "BÅ‚Ä…d Å‚adowania fonta." msgid "Invalid font size." msgstr "Niepoprawny rozmiar fonta." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "nieprawidÅ‚owy format pliku version.txt wewnÄ…trz szablonów. Zmiana nie " +#~ "jest prawidÅ‚owym identyfikatorem." + +#~ msgid "Can't write file." +#~ msgstr "Nie można zapisać pliku." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "ProszÄ™ wybrać folder nie zawierajÄ…cy pliku 'project.godot'." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "Nie można byÅ‚o utworzyć engine.cfg w Å›cieżce projektu." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "Nie znaleziono project.godot w Å›cieżce projektu." + #~ msgid "Next" #~ msgstr "NastÄ™pny" diff --git a/editor/translations/pr.po b/editor/translations/pr.po index 3fd24dd39f..6029e861fd 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -2382,12 +2382,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2441,10 +2435,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3622,15 +3612,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4461,6 +4451,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4745,10 +4751,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "Yar, Blow th' Selected Down!" @@ -4762,6 +4764,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5609,11 +5615,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5874,10 +5875,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5898,7 +5895,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5919,10 +5918,6 @@ msgid "Rename Project" msgstr "Rename Function" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6616,10 +6611,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6732,10 +6723,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7170,32 +7157,44 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "GridMap Delete Selection" -msgstr "Yar, Blow th' Selected Down!" +msgid "Next Plane" +msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Delete Selection" +msgstr "Yar, Blow th' Selected Down!" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Duplicate Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7304,6 +7303,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7319,6 +7322,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7847,6 +7854,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index 6963d39352..ae67217cfd 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -9,13 +9,14 @@ # Francesco Perrotti-Garcia <fpg1503@gmail.com>, 2017. # George Marques <george@gmarqu.es>, 2016. # Guilherme Felipe C G Silva <guilhermefelipecgs@gmail.com>, 2017. +# João Vitor de Oliveira Carlos <lopogax@gmail.com>, 2018. # Joaquim Ferreira <joaquimferreira1996@bol.com.br>, 2016. # jonathan railarem <railarem@gmail.com>, 2017. # Lucas Silva <lucasb.hpp@gmail.com>, 2018. # Luiz G. Correia <luizgabriell2.0@gmail.com>, 2017. # Mailson Silva Marins <mailsons335@gmail.com>, 2016. # MalcomRF <malcomkbk@gmail.com>, 2017. -# Marcus Correia <marknokalt@live.com>, 2017. +# Marcus Correia <marknokalt@live.com>, 2017-2018. # Michael Alexsander Silva Dias <michaelalexsander@protonmail.com>, 2017-2018. # Renato Rotenberg <renato.rotenberg@gmail.com>, 2017. # Rodolfo R Gomes <rodolforg@gmail.com>, 2017. @@ -25,7 +26,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2018-01-22 08:08+0000\n" +"PO-Revision-Date: 2018-02-22 20:49+0000\n" "Last-Translator: Michael Alexsander Silva Dias <michaelalexsander@protonmail." "com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" @@ -35,7 +36,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -47,7 +48,7 @@ msgstr "Toda a Seleção" #: editor/animation_editor.cpp msgid "Anim Change Keyframe Time" -msgstr "Alterar tempo de quadro-chave da animação" +msgstr "Alterar Tempo de Quadro-Chave da Anim" #: editor/animation_editor.cpp msgid "Anim Change Transition" @@ -59,7 +60,7 @@ msgstr "Alterar Transformação da Anim" #: editor/animation_editor.cpp msgid "Anim Change Keyframe Value" -msgstr "Alterar valor de quadro-chave da animação" +msgstr "Alterar Valor de Quadro-Chave da Anim" #: editor/animation_editor.cpp msgid "Anim Change Call" @@ -433,7 +434,7 @@ msgstr "Coluna:" #: editor/connections_dialog.cpp msgid "Method in target Node must be specified!" -msgstr "O método no Nó destino precisa ser especificado!" +msgstr "O método no nó destino precisa ser especificado!" #: editor/connections_dialog.cpp msgid "" @@ -441,7 +442,7 @@ msgid "" "Node." msgstr "" "Método destino não encontrado! EspecÃfique um método válido ou anexe um " -"script ao Nó destino." +"script ao nó destino." #: editor/connections_dialog.cpp msgid "Connect To Node:" @@ -470,7 +471,7 @@ msgstr "Argumentos de Chamada Extras:" #: editor/connections_dialog.cpp msgid "Path to Node:" -msgstr "Caminho para o Nó:" +msgstr "Caminho para o nó:" #: editor/connections_dialog.cpp msgid "Make Function" @@ -482,7 +483,7 @@ msgstr "Postergado" #: editor/connections_dialog.cpp msgid "Oneshot" -msgstr "Uma vez" +msgstr "Oneshot" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp @@ -1063,7 +1064,7 @@ msgstr "Caminho:" #: editor/editor_autoload_settings.cpp msgid "Node Name:" -msgstr "Nome do Nó:" +msgstr "Nome do nó:" #: editor/editor_autoload_settings.cpp editor/editor_profiler.cpp #: editor/project_manager.cpp editor/settings_config_dialog.cpp @@ -1653,11 +1654,11 @@ msgstr "Abrir Cena Base" #: editor/editor_node.cpp msgid "Quick Open Scene.." -msgstr "Abri Cena Ãgil..." +msgstr "Abri Cena Rápidamente..." #: editor/editor_node.cpp msgid "Quick Open Script.." -msgstr "Abrir Rápidamente Script.." +msgstr "Abrir Script Rápidamente..." #: editor/editor_node.cpp msgid "Save & Close" @@ -2417,7 +2418,7 @@ msgstr "Padrão (Mesma do Editor)" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" -msgstr "Selecionar Nó(s) para Importar" +msgstr "Selecione Nó(s) para Importar" #: editor/editor_sub_scene.cpp msgid "Scene Path:" @@ -2468,14 +2469,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Formato do version.txt dentro dos modelos é inválido." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Formato do version.txt dentro dos modelos é inválido. A revisão não é um " -"identificador válido." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Não foi encontrado um version.txt dentro dos modelos." @@ -2530,10 +2523,6 @@ msgid "Failed:" msgstr "Falhou:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Não foi possÃvel escrever o arquivo." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Download completo." @@ -2883,7 +2872,7 @@ msgstr "Reimportar" #: editor/multi_node_edit.cpp msgid "MultiNode Set" -msgstr "Múltiplos Nós definidos" +msgstr "Múltiplos Nodes definidos" #: editor/node_dock.cpp msgid "Groups" @@ -2891,7 +2880,7 @@ msgstr "Grupos" #: editor/node_dock.cpp msgid "Select a Node to edit Signals and Groups." -msgstr "Selecione um Nó para editar Sinais e Grupos." +msgstr "Selecione um nó para editar Sinais e Grupos." #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -3260,39 +3249,39 @@ msgstr "Ãrvore de Animação é inválida." #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Animation Node" -msgstr "Nó de Animação" +msgstr "Nó Animation" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "OneShot Node" -msgstr "Nó de tipo Uma-Vez" +msgstr "Nó OneShot" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Mix Node" -msgstr "Misturar Nó" +msgstr "Nó Mix" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend2 Node" -msgstr "Nó Misturar2" +msgstr "Nó Blend2" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend3 Node" -msgstr "Nó Misturar3" +msgstr "Nó Blend3" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Blend4 Node" -msgstr "Nó Misturar4" +msgstr "Nó Blend4" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeScale Node" -msgstr "Nó Tempo de Escala" +msgstr "Nó TimeScale" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "TimeSeek Node" -msgstr "Nó Tempo de Procura" +msgstr "Nó TimeSeek" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Transition Node" -msgstr "Nó de Transição" +msgstr "Nó Transition" #: editor/plugins/animation_tree_editor_plugin.cpp msgid "Import Animations.." @@ -3720,15 +3709,15 @@ msgid "Show Grid" msgstr "Mostrar Grade" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Mostrar auxiliadores" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Mostrar réguas" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Mostrar guias" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4558,6 +4547,22 @@ msgid "Resource clipboard is empty!" msgstr "Recurso da área de transferência está vazio!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Abrir no Editor" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Instância:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Tipo:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Carregar Recurso" @@ -4844,10 +4849,6 @@ msgid "Toggle Comment" msgstr "Alternar Comentário" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Clonar Abaixo" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "Dobrar/Desdobrar Linha" @@ -4860,6 +4861,10 @@ msgid "Unfold All Lines" msgstr "Mostrar Todas as Linhas" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Clonar Abaixo" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "Completar SÃmbolo" @@ -5018,11 +5023,11 @@ msgstr "Alterar Nome da Entrada" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Connect Graph Nodes" -msgstr "Conectar Nós de Grafos" +msgstr "Conectar Nodes de Grafos" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Disconnect Graph Nodes" -msgstr "Desconectar Nós de Grafos" +msgstr "Desconectar Nodes de Grafos" #: editor/plugins/shader_graph_editor_plugin.cpp msgid "Remove Shader Graph Node" @@ -5703,11 +5708,6 @@ msgstr "Guia 2" msgid "Tab 3" msgstr "Guia 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Tipo:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Tipo de Dados:" @@ -5979,11 +5979,6 @@ msgid "Please choose an empty folder." msgstr "Por favor, escolha uma pasta vazia." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" -"Por favor, escolha uma pasta que não contenha um arquivo 'project.godot'." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Projeto Importado" @@ -6004,8 +5999,12 @@ msgid "Invalid project path (changed anything?)." msgstr "Caminho de projeto inválido (mudou alguma coisa?)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "Não foi possÃvel encontrar project.godot no caminho do projeto." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" +"Não foi possÃvel carregar project.godot no caminho do projeto (erro %d). Ele " +"pode estar ausente ou corrompido." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -6024,10 +6023,6 @@ msgid "Rename Project" msgstr "Renomear Projeto" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "Não foi possÃvel encontrar project.godot no caminho do projeto." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Novo Projeto de Jogo" @@ -6540,7 +6535,7 @@ msgstr "Erro ao carregar arquivo: Não é um recurso!" #: editor/property_editor.cpp msgid "Selected node is not a Viewport!" -msgstr "Nó selecionado não é uma Viewport!" +msgstr "O nó selecionado não é uma Viewport!" #: editor/property_editor.cpp msgid "Pick a Node" @@ -6657,7 +6652,7 @@ msgstr "Mover Nó no Pai" #: editor/scene_tree_dock.cpp msgid "Move Nodes In Parent" -msgstr "Mover Nós no Pai" +msgstr "Mover Nodes no Pai" #: editor/scene_tree_dock.cpp msgid "Duplicate Node(s)" @@ -6731,10 +6726,6 @@ msgstr "Sub-Recursos" msgid "Clear Inheritance" msgstr "Limpar Herança" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Abrir no Editor" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Excluir Nó(s)" @@ -6784,8 +6775,8 @@ msgid "" "Instance a scene file as a Node. Creates an inherited scene if no root node " "exists." msgstr "" -"Instanciar um arquivo de cena como um Nó. Criar uma cena herdada se não " -"existe um nó raiz." +"Instanciar um arquivo de cena como um nó. Cria uma cena herdada se não " +"existir um nó raiz." #: editor/scene_tree_dock.cpp msgid "Filter nodes" @@ -6852,10 +6843,6 @@ msgstr "" "Clique para mostrar o painel de grupos." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "Instância:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Abrir script" @@ -6889,7 +6876,7 @@ msgstr "Renomear Nó" #: editor/scene_tree_editor.cpp msgid "Scene Tree (Nodes):" -msgstr "Ãrvore de Cena (Nós):" +msgstr "Ãrvore de Cena (Nodes):" #: editor/scene_tree_editor.cpp msgid "Node Configuration Warning!" @@ -7284,32 +7271,44 @@ msgid "Object can't provide a length." msgstr "Objeto não pôde fornecer um comprimento." #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "Excluir Seleção do Gridap" +msgid "Next Plane" +msgstr "Próximo Plano" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "Duplicar Seleção do GridMap" +msgid "Previous Plane" +msgstr "Plano Anterior" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "Plano:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "Próximo Chão" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Chão Anterior" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "Chão:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "Mapa de Grade" +msgid "GridMap Delete Selection" +msgstr "Excluir Seleção do Gridap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "Ancorar Vista" +msgid "GridMap Duplicate Selection" +msgstr "Duplicar Seleção do GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "Chão Anterior" +msgid "Grid Map" +msgstr "Mapa de Grade" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "Próximo Chão" +msgid "Snap View" +msgstr "Ancorar Vista" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7416,6 +7415,10 @@ msgid "Mono" msgstr "Mono" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "Sobre o suporte ao C#" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "Criar solução C#" @@ -7431,6 +7434,10 @@ msgstr "Compilar Projeto" msgid "Warnings" msgstr "Avisos" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7453,7 +7460,7 @@ msgid "" "your node please." msgstr "" "Um valor de retorno deve ser atribuÃdo ao primeiro elemento da memória " -"corrente do nó! Conserte seu node, por favor." +"corrente do nó! Conserte seu nó, por favor." #: modules/visual_script/visual_script.cpp msgid "Node returned an invalid sequence output: " @@ -7537,11 +7544,11 @@ msgstr "Adicionar Nó" #: modules/visual_script/visual_script_editor.cpp msgid "Remove VisualScript Nodes" -msgstr "Remover Nós VisualScript" +msgstr "Remover Nodes VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Duplicate VisualScript Nodes" -msgstr "Duplicar Nós VisualScript" +msgstr "Duplicar Nodes VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." @@ -7577,7 +7584,7 @@ msgstr "Adicionar Nó de Pré-carregamento" #: modules/visual_script/visual_script_editor.cpp msgid "Add Node(s) From Tree" -msgstr "Adicionar Nó(s) a partir de árvore" +msgstr "Adicionar Nó(s) a Partir da Ãrvore" #: modules/visual_script/visual_script_editor.cpp msgid "Add Getter Property" @@ -7601,7 +7608,7 @@ msgstr "Remover Nó VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Connect Nodes" -msgstr "Conectar Nós" +msgstr "Conectar Nodes" #: modules/visual_script/visual_script_editor.cpp msgid "Condition" @@ -7653,7 +7660,7 @@ msgstr "Ãrea de transferência vazia!" #: modules/visual_script/visual_script_editor.cpp msgid "Paste VisualScript Nodes" -msgstr "Colar Nós VisualScript" +msgstr "Colar Nodes VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Remove Function" @@ -7689,7 +7696,7 @@ msgstr "Tipo de Base:" #: modules/visual_script/visual_script_editor.cpp msgid "Available Nodes:" -msgstr "Nós DisponÃveis:" +msgstr "Nodes DisponÃveis:" #: modules/visual_script/visual_script_editor.cpp msgid "Select or create a function to edit graph" @@ -7713,15 +7720,15 @@ msgstr "Localizar Tipo de Nó" #: modules/visual_script/visual_script_editor.cpp msgid "Copy Nodes" -msgstr "Copiar Nós" +msgstr "Copiar Nodes" #: modules/visual_script/visual_script_editor.cpp msgid "Cut Nodes" -msgstr "Recortar Nós" +msgstr "Recortar Nodes" #: modules/visual_script/visual_script_editor.cpp msgid "Paste Nodes" -msgstr "Colar Nós" +msgstr "Colar Nodes" #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " @@ -7741,11 +7748,11 @@ msgstr "Nome da propriedade de Ãndice inválido." #: modules/visual_script/visual_script_func_nodes.cpp msgid "Base object is not a Node!" -msgstr "Objeto base não é um Node!" +msgstr "Objeto base não é um nó!" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Path does not lead Node!" -msgstr "O caminho não leva a um Node!" +msgstr "O caminho não leva a um nó!" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name '%s' in node %s." @@ -7985,6 +7992,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin necessita um nó ARVRCamera como filho" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "%d%%" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "(Tempo Restante: %d:%02d s)" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "Planejando Malhas: " @@ -8184,6 +8199,26 @@ msgstr "Erro ao carregar fonte." msgid "Invalid font size." msgstr "Tamanho de fonte inválido." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Formato do version.txt dentro dos modelos é inválido. A revisão não é um " +#~ "identificador válido." + +#~ msgid "Can't write file." +#~ msgstr "Não foi possÃvel escrever o arquivo." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "" +#~ "Por favor, escolha uma pasta que não contenha um arquivo 'project.godot'." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "Não foi possÃvel encontrar project.godot no caminho do projeto." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "Não foi possÃvel encontrar project.godot no caminho do projeto." + #~ msgid "Next" #~ msgstr "Próximo" diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po index 7bddb64cd0..9f520ddf46 100644 --- a/editor/translations/pt_PT.po +++ b/editor/translations/pt_PT.po @@ -8,6 +8,7 @@ # João Graça <jgraca95@gmail.com>, 2017. # João Lopes <linux-man@hotmail.com>, 2017-2018. # Miguel Gomes <miggas09@gmail.com>, 2017. +# Paulo Caldeira <paucal@gmail.com>, 2018. # Pedro Gomes <pedrogomes1698@gmail.com>, 2017. # Rueben Stevens <supercell03@gmail.com>, 2017. # SARDON <fabio3_Santos@hotmail.com>, 2017. @@ -16,15 +17,15 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-01-22 08:08+0000\n" -"Last-Translator: João Lopes <linux-man@hotmail.com>\n" +"PO-Revision-Date: 2018-02-24 23:41+0000\n" +"Last-Translator: Paulo Caldeira <paucal@gmail.com>\n" "Language-Team: Portuguese (Portugal) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_PT/>\n" "Language: pt_PT\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -837,7 +838,7 @@ msgstr "Alterar Volume do canal áudio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Solo" -msgstr "Alternar solo do canal áudio" +msgstr "Alternar solo do canal de áudio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Mute" @@ -845,7 +846,7 @@ msgstr "Alternar silêncio do canal áudio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Bypass Effects" -msgstr "Alternar efeitos do canal áudio" +msgstr "Alternar efeitos bypass do canal de áudio" #: editor/editor_audio_buses.cpp msgid "Select Audio Bus Send" @@ -1097,7 +1098,7 @@ msgstr "Escolha uma Diretoria" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp msgid "Create Folder" -msgstr "Criar Pasta/Diretoria" +msgstr "Criar Pasta" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp @@ -2458,14 +2459,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Formato de version.txt inválido, dentro dos Modelos." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Formato de version.txt inválido, dentro dos Modelos. Revisão não é um " -"identificador válido." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Não foi encontrado version.txt dentro dos Modelos." @@ -2520,10 +2513,6 @@ msgid "Failed:" msgstr "Falhou:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "ImpossÃvel escrever o Ficheiro." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Download Completo." @@ -3435,7 +3424,7 @@ msgstr "Oficial" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Testing" -msgstr "A testar" +msgstr "Em teste" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" @@ -3705,15 +3694,15 @@ msgid "Show Grid" msgstr "Mostrar grelha" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Mostrar ajudantes" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Mostrar réguas" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Mostrar guias" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4540,6 +4529,22 @@ msgid "Resource clipboard is empty!" msgstr "Ãrea de transferência de recursos vazia!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Abrir no Editor" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Instância:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Tipo:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Carregar recurso" @@ -4826,10 +4831,6 @@ msgid "Toggle Comment" msgstr "Alternar comentário" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Clonar abaixo" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "Fechar/Abrir Linha" @@ -4842,6 +4843,10 @@ msgid "Unfold All Lines" msgstr "Mostrar todas as linhas" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Clonar abaixo" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "Completar sÃmbolo" @@ -5685,11 +5690,6 @@ msgstr "Aba 2" msgid "Tab 3" msgstr "Aba 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Tipo:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Tipo de dados:" @@ -5959,10 +5959,6 @@ msgid "Please choose an empty folder." msgstr "Por favor escolha uma pasta vazia." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "Escolha uma pasta que não contenha um Ficheiro 'project.godot'." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Projeto importado" @@ -5983,8 +5979,12 @@ msgid "Invalid project path (changed anything?)." msgstr "Caminho de Projeto inválido (alguma alteração?)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "ImpossÃvel encontrar project.godot no Caminho do Projeto." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" +"Não foi possÃvel carregar o project.godot no caminho do projeto. Poderá " +"estar em falta ou corrompido." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -6003,10 +6003,6 @@ msgid "Rename Project" msgstr "Renomear Projeto" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "ImpossÃvel encontrar project.godot no Caminho do Projeto." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Novo Projeto de jogo" @@ -6709,10 +6705,6 @@ msgstr "Sub-recursos" msgid "Clear Inheritance" msgstr "Limpar herança" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Abrir no Editor" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Apagar Nó(s)" @@ -6830,10 +6822,6 @@ msgstr "" "Clique para mostrar doca dos grupos." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "Instância:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Abrir Script" @@ -7263,32 +7251,44 @@ msgid "Object can't provide a length." msgstr "Objeto não fornece um comprimento." #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "Apagar seleção GridMap" +msgid "Next Plane" +msgstr "Plano seguinte" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "Seleção duplicada de GridMap" +msgid "Previous Plane" +msgstr "Plano anterior" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "Plano:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "Próximo Piso" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Piso anterior" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "Piso:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "Mapa de grelha" +msgid "GridMap Delete Selection" +msgstr "Apagar seleção GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "Vista de Ajuste" +msgid "GridMap Duplicate Selection" +msgstr "Seleção duplicada de GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "Piso anterior" +msgid "Grid Map" +msgstr "Mapa de grelha" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "Próximo Piso" +msgid "Snap View" +msgstr "Vista de Ajuste" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7395,6 +7395,10 @@ msgid "Mono" msgstr "Mono" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "Sobre o suporte C#" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "Criar solução C#" @@ -7410,6 +7414,10 @@ msgstr "Construir Projeto" msgid "Warnings" msgstr "Avisos" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7963,6 +7971,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin exige um Nó filho ARVRCamera" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "%d%%" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "(Tempo restante: %d:%02d s)" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "A traçar Meshes: " @@ -8164,6 +8180,25 @@ msgstr "Erro ao carregar letra." msgid "Invalid font size." msgstr "Tamanho de letra inválido." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Formato de version.txt inválido, dentro dos Modelos. Revisão não é um " +#~ "identificador válido." + +#~ msgid "Can't write file." +#~ msgstr "ImpossÃvel escrever o Ficheiro." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "Escolha uma pasta que não contenha um Ficheiro 'project.godot'." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "ImpossÃvel encontrar project.godot no Caminho do Projeto." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "ImpossÃvel encontrar project.godot no Caminho do Projeto." + #~ msgid "Next" #~ msgstr "Proximo" diff --git a/editor/translations/ro.po b/editor/translations/ro.po index 9aa5fbeeff..1d89dd74ea 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -2364,12 +2364,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2422,10 +2416,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3588,15 +3578,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4419,6 +4409,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4701,10 +4707,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "" @@ -4717,6 +4719,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5557,11 +5563,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5821,10 +5822,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5845,7 +5842,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5865,10 +5864,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6556,10 +6551,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6669,10 +6660,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7095,11 +7082,23 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +msgid "Next Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7107,19 +7106,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7227,6 +7226,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7242,6 +7245,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7741,6 +7748,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/editor/translations/ru.po b/editor/translations/ru.po index cf82142c80..67e02b9ce8 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-01-24 12:27+0000\n" +"PO-Revision-Date: 2018-02-23 20:40+0000\n" "Last-Translator: ijet <my-ijet@mail.ru>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" @@ -28,7 +28,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -2459,14 +2459,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Ðеверный формат version.txt файла внутри шаблонов." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Ðеверный формат version.txt файла внутри шаблонов. Идентификатор ревизии не " -"верен." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Ðе найден version.txt файл в шаблонах." @@ -2521,10 +2513,6 @@ msgid "Failed:" msgstr "Ðе удалоÑÑŒ:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Ðе удалоÑÑŒ запиÑать файл." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Загрузка завершена." @@ -3711,15 +3699,15 @@ msgid "Show Grid" msgstr "Показать Ñетку" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Показывать помощники" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Показывать линейки" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Показывать направлÑющие" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4546,6 +4534,22 @@ msgid "Resource clipboard is empty!" msgstr "Ðет реÑурÑа в буфере обмена!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Открыть в редакторе" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "ÐкземплÑÑ€:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Тип:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Загрузить реÑурÑ" @@ -4832,10 +4836,6 @@ msgid "Toggle Comment" msgstr "Переключить комментарий" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Копировать вниз" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "Свернуть/Развернуть Ñтроку" @@ -4848,6 +4848,10 @@ msgid "Unfold All Lines" msgstr "Развернуть вÑе Ñтроки" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Копировать вниз" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "СпиÑок автозавершениÑ" @@ -5693,11 +5697,6 @@ msgstr "Вкладка 2" msgid "Tab 3" msgstr "Вкладка 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Тип:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Тип информации:" @@ -5963,10 +5962,6 @@ msgid "Please choose an empty folder." msgstr "ПожалуйÑта, выберите пуÑтую папку." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "ПожалуйÑта, выберите папку, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ðµ Ñодержит файл 'project.godot'." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Импортированный проект" @@ -5987,8 +5982,12 @@ msgid "Invalid project path (changed anything?)." msgstr "Ðеверный путь к проекту (Что-то изменили?)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "ОтÑутÑтвует project.godot в папке проекта." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" +"Ðе удалоÑÑŒ загрузить project.godot в пути проекта (ошибка %d). Возможно, он " +"отÑутÑтвует или поврежден." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -6007,10 +6006,6 @@ msgid "Rename Project" msgstr "Переименовать проект" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "ОтÑутÑтвует project.godot в папке проекта." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Ðовый игровой проект" @@ -6715,10 +6710,6 @@ msgstr "Вложенные реÑурÑÑ‹" msgid "Clear Inheritance" msgstr "ОчиÑтить наÑледование" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Открыть в редакторе" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Удалить узел(узлы)" @@ -6836,10 +6827,6 @@ msgstr "" "Ðажмите, чтобы показать панель групп." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "ÐкземплÑÑ€:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Открыть Ñкрипт" @@ -7268,32 +7255,44 @@ msgid "Object can't provide a length." msgstr "Объект не может предоÑтавить длину." #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "Удалить выделенную Ñетку" +msgid "Next Plane" +msgstr "Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð¿Ð¾ÑкоÑÑ‚ÑŒ" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "Дублировать выделенную Ñетку" +msgid "Previous Plane" +msgstr "ÐŸÑ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ Ð¿Ð»Ð¾ÑкоÑÑ‚ÑŒ" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "ПлоÑкоÑÑ‚ÑŒ:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "Следующий Ñтаж" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Предыдущий Ñтаж" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "Ðтаж:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "Ð¡ÐµÑ‚Ð¾Ñ‡Ð½Ð°Ñ ÐºÐ°Ñ€Ñ‚Ð°" +msgid "GridMap Delete Selection" +msgstr "Удалить выделенную Ñетку" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "ПривÑзать вид" +msgid "GridMap Duplicate Selection" +msgstr "Дублировать выделенную Ñетку" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "Предыдущий Ñтаж" +msgid "Grid Map" +msgstr "Ð¡ÐµÑ‚Ð¾Ñ‡Ð½Ð°Ñ ÐºÐ°Ñ€Ñ‚Ð°" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "Следующий Ñтаж" +msgid "Snap View" +msgstr "ПривÑзать вид" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7400,6 +7399,10 @@ msgid "Mono" msgstr "Моно" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "О C# поддержке" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "Создать C# решение" @@ -7415,6 +7418,10 @@ msgstr "Собрать проект" msgid "Warnings" msgstr "ПредупреждениÑ" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7818,6 +7825,10 @@ msgid "" "Consider adding CollisionShape2D or CollisionPolygon2D children nodes to " "define its shape." msgstr "" +"Ðтот узел не имеет дочерних форм, поÑтому он не может взаимодейÑтвовать Ñ " +"проÑтранÑтвом.\n" +"РаÑÑмотрите возможноÑÑ‚ÑŒ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ CollisionShape2D или CollisionPolygon2D " +"дочерних узлов, Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ формы." #: scene/2d/collision_polygon_2d.cpp msgid "" @@ -7965,6 +7976,15 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin требует дочерний узел ARVRCamera" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +#, fuzzy +msgid "(Time Left: %d:%02d s)" +msgstr "(ОÑталоÑÑŒ: %d:%02d Ñек)" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "ПоÑтроение полиÑетки: " @@ -7986,6 +8006,10 @@ msgid "" "Consider adding CollisionShape or CollisionPolygon children nodes to define " "its shape." msgstr "" +"Ðтот узел не имеет дочерних форм, поÑтому он не может взаимодейÑтвовать Ñ " +"проÑтранÑтвом.\n" +"РаÑÑмотрите возможноÑÑ‚ÑŒ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ CollisionShape или CollisionPolygon " +"дочерних узлов, чтобы определить его форму." #: scene/3d/collision_polygon.cpp msgid "" @@ -8161,6 +8185,26 @@ msgstr "Ошибка загрузки шрифта." msgid "Invalid font size." msgstr "ÐедопуÑтимый размер шрифта." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Ðеверный формат version.txt файла внутри шаблонов. Идентификатор ревизии " +#~ "не верен." + +#~ msgid "Can't write file." +#~ msgstr "Ðе удалоÑÑŒ запиÑать файл." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "" +#~ "ПожалуйÑта, выберите папку, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ðµ Ñодержит файл 'project.godot'." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "ОтÑутÑтвует project.godot в папке проекта." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "ОтÑутÑтвует project.godot в папке проекта." + #~ msgid "Next" #~ msgstr "Следующий" diff --git a/editor/translations/sk.po b/editor/translations/sk.po index 33c848f91b..c5fa76fb01 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -2385,12 +2385,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2443,11 +2437,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -#, fuzzy -msgid "Can't write file." -msgstr "Popis:" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3623,15 +3612,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4465,6 +4454,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4748,10 +4753,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "" @@ -4764,6 +4765,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5612,11 +5617,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5879,10 +5879,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5904,7 +5900,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5925,10 +5923,6 @@ msgid "Rename Project" msgstr "VÅ¡etky vybrané" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6623,10 +6617,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6740,10 +6730,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "Popis:" @@ -7174,32 +7160,44 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "GridMap Delete Selection" -msgstr "VÅ¡etky vybrané" +msgid "Next Plane" +msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Delete Selection" +msgstr "VÅ¡etky vybrané" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Duplicate Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7309,6 +7307,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7324,6 +7326,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7840,6 +7846,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8001,6 +8015,10 @@ msgstr "" msgid "Invalid font size." msgstr "" +#, fuzzy +#~ msgid "Can't write file." +#~ msgstr "Popis:" + #~ msgid "Meta+" #~ msgstr "Meta+" diff --git a/editor/translations/sl.po b/editor/translations/sl.po index 9e9db80294..04fb6d9816 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -2380,12 +2380,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2438,10 +2432,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3618,15 +3608,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4457,6 +4447,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4741,10 +4747,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "IzbriÅ¡i Izbrano" @@ -4758,6 +4760,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5604,11 +5610,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5869,10 +5870,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5893,7 +5890,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5914,10 +5913,6 @@ msgid "Rename Project" msgstr "Preimenuj Funkcijo" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6611,10 +6606,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6725,10 +6716,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7157,32 +7144,44 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "GridMap Delete Selection" -msgstr "IzbriÅ¡i Izbrano" +msgid "Next Plane" +msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Delete Selection" +msgstr "IzbriÅ¡i Izbrano" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Duplicate Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7291,6 +7290,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7306,6 +7309,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7835,6 +7842,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index 1c53884f32..e411ff2305 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -2453,14 +2453,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Ðеважећи формат датотеке version.txt унутар шаблона." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Ðеважећи формат датотеке „version.txt“ унутар шаблона. „Revision“ није " -"важећи идентификатор." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "„version.txt“ није пронаћен у шаблону." @@ -2517,10 +2509,6 @@ msgid "Failed:" msgstr "ÐеуÑпех:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "ÐеуÑпех при запиÑивању датотеке." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Преузимање уÑпешно." @@ -3710,15 +3698,15 @@ msgid "Show Grid" msgstr "Покажи мрежу" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Покажи помагаче" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Покажи лељире" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Покажи водиче" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4548,6 +4536,22 @@ msgid "Resource clipboard is empty!" msgstr "Ðема реÑурÑа за копирање!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Тип:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Учитај реÑурÑ" @@ -4840,10 +4844,6 @@ msgid "Toggle Comment" msgstr "Коментариши" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Клонирај доле" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "Откриј линију" @@ -4857,6 +4857,10 @@ msgid "Unfold All Lines" msgstr "Откриј Ñве линије" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Клонирај доле" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "Потпун Ñимбол" @@ -5710,11 +5714,6 @@ msgstr "Tab 2" msgid "Tab 3" msgstr "Tab 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Тип:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Тип податка:" @@ -5988,10 +5987,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -6013,7 +6008,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -6033,10 +6030,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6730,10 +6723,6 @@ msgstr "РеÑурÑи" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6843,10 +6832,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7271,31 +7256,45 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +#, fuzzy +msgid "Next Plane" +msgstr "Следећи таб" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "Previous Plane" +msgstr "Претходни таб" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Претодни Ñпрат" + +#: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "Мапа мреже" +msgid "GridMap Delete Selection" +msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "Претодни Ñпрат" +msgid "Grid Map" +msgstr "Мапа мреже" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7408,6 +7407,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "Ðаправи ивице" @@ -7425,6 +7428,10 @@ msgstr "Пројекат" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7930,6 +7937,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8091,6 +8106,16 @@ msgstr "" msgid "Invalid font size." msgstr "Ðеважећа величина фонта." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Ðеважећи формат датотеке „version.txt“ унутар шаблона. „Revision“ није " +#~ "важећи идентификатор." + +#~ msgid "Can't write file." +#~ msgstr "ÐеуÑпех при запиÑивању датотеке." + #~ msgid "Next" #~ msgstr "Следеће" diff --git a/editor/translations/sv.po b/editor/translations/sv.po index 5779cb56b1..64a268a7bc 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -2699,12 +2699,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2760,10 +2754,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp #, fuzzy msgid "Download Complete." msgstr "Nedladdning Klar." @@ -3987,15 +3977,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4839,6 +4829,24 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +#, fuzzy +msgid "Instance:" +msgstr "Instans:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +#, fuzzy +msgid "Type:" +msgstr "Typ:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Ladda Resurs" @@ -5151,10 +5159,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "" @@ -5167,6 +5171,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -6052,12 +6060,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -#, fuzzy -msgid "Type:" -msgstr "Typ:" - #: editor/plugins/theme_editor_plugin.cpp #, fuzzy msgid "Data Type:" @@ -6331,10 +6333,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -6357,7 +6355,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -6378,10 +6378,6 @@ msgid "Rename Project" msgstr "Byt namn pÃ¥ Projekt" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp #, fuzzy msgid "New Game Project" msgstr "Nytt Spelprojekt" @@ -7122,10 +7118,6 @@ msgstr "Resurser" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp #, fuzzy msgid "Delete Node(s)" @@ -7244,11 +7236,6 @@ msgstr "" #: editor/scene_tree_editor.cpp #, fuzzy -msgid "Instance:" -msgstr "Instans:" - -#: editor/scene_tree_editor.cpp -#, fuzzy msgid "Open script" msgstr "Öppna Skript" @@ -7708,11 +7695,25 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +#, fuzzy +msgid "Next Plane" +msgstr "Nästa flik" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "Previous Plane" +msgstr "FöregÃ¥ende flik" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7720,19 +7721,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7849,6 +7850,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "Skapa Prenumeration" @@ -7867,6 +7872,10 @@ msgstr "Projekt" msgid "Warnings" msgstr "Varning" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -8414,6 +8423,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin kräver en ARVRCamera Barn-Node" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/editor/translations/ta.po b/editor/translations/ta.po index 16e646b2a0..4be5e8b832 100644 --- a/editor/translations/ta.po +++ b/editor/translations/ta.po @@ -2365,12 +2365,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2423,10 +2417,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3590,15 +3580,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4421,6 +4411,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4703,10 +4709,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "" @@ -4719,6 +4721,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5559,11 +5565,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5823,10 +5824,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5847,7 +5844,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5867,10 +5866,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6558,10 +6553,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6671,10 +6662,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7097,11 +7084,23 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +msgid "Next Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7109,19 +7108,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7229,6 +7228,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7244,6 +7247,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7743,6 +7750,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/editor/translations/th.po b/editor/translations/th.po index 4f8b834985..b31fba186a 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2018-01-20 09:49+0000\n" +"PO-Revision-Date: 2018-02-25 04:41+0000\n" "Last-Translator: Poommetee Ketson <poommetee@protonmail.com>\n" "Language-Team: Thai <https://hosted.weblate.org/projects/godot-engine/godot/" "th/>\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -102,11 +102,11 @@ msgstr "ลบคีย์à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_editor.cpp editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Duplicate Selection" -msgstr "ทำซ้ำในà¹à¸—ร็à¸à¹€à¸”ิม" +msgstr "ทำซ้ำที่เลืà¸à¸" #: editor/animation_editor.cpp msgid "Duplicate Transposed" -msgstr "ทำซ้ำในà¹à¸—ร็à¸à¸—ี่เลืà¸à¸" +msgstr "ทำซ้ำเปลี่ยนà¹à¸—ร็à¸" #: editor/animation_editor.cpp msgid "Remove Selection" @@ -2404,12 +2404,6 @@ msgid "Invalid version.txt format inside templates." msgstr "รูปà¹à¸šà¸šà¸‚à¸à¸‡ version.txt ในà¹à¸¡à¹ˆà¹à¸šà¸šà¹„ม่ถูà¸à¸•à¹‰à¸à¸‡" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "รูปà¹à¸šà¸šà¸‚à¸à¸‡ version.txt ในà¹à¸¡à¹ˆà¹à¸šà¸šà¹„ม่ถูà¸à¸•à¹‰à¸à¸‡ หมายเลขรุ่น revision ต้à¸à¸‡à¹ƒà¸Šà¹‰à¸£à¸°à¸šà¸¸à¹„ด้" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "ไม่พบ version.txt ในà¹à¸¡à¹ˆà¹à¸šà¸š" @@ -2462,10 +2456,6 @@ msgid "Failed:" msgstr "ผิดพลาด:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "เขียนไฟล์ไม่ได้" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "ดาวน์โหลดเสร็จสิ้น" @@ -3639,15 +3629,15 @@ msgid "Show Grid" msgstr "à¹à¸ªà¸”งเส้นตาราง" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "à¹à¸ªà¸”งตัวช่วย" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "à¹à¸ªà¸”งไม้บรรทัด" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "à¹à¸ªà¸”งเส้นนำ" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4474,6 +4464,22 @@ msgid "Resource clipboard is empty!" msgstr "คลิปบà¸à¸£à¹Œà¸”ไม่มีรีซà¸à¸£à¹Œà¸ª!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "เปิดในโปรà¹à¸à¸£à¸¡à¹à¸à¹‰à¹„ข" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "à¸à¸´à¸™à¸ªà¹à¸•à¸™à¸‹à¹Œ:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "ประเภท:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "โหลดรีซà¸à¸£à¹Œà¸ª" @@ -4758,10 +4764,6 @@ msgid "Toggle Comment" msgstr "เปิด/ปิด ความคิดเห็น" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "คัดลà¸à¸à¸šà¸£à¸£à¸—ัดลงมา" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "ซ่à¸à¸™/à¹à¸ªà¸”งบรรทัด" @@ -4774,6 +4776,10 @@ msgid "Unfold All Lines" msgstr "à¹à¸ªà¸”งทั้งหมด" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "คัดลà¸à¸à¸šà¸£à¸£à¸—ัดลงมา" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "เสนà¸à¹à¸™à¸°à¸„ำเต็ม" @@ -5617,11 +5623,6 @@ msgstr "à¹à¸—็บ 2" msgid "Tab 3" msgstr "à¹à¸—็บ 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "ประเภท:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "ชนิดข้à¸à¸¡à¸¹à¸¥:" @@ -5680,15 +5681,15 @@ msgstr "ค้นหา tile" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Transpose" -msgstr "สลับเปลี่ยน" +msgstr "สลับà¹à¸à¸™" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Mirror X" -msgstr "สะท้à¸à¸™à¸šà¸™à¸¥à¹ˆà¸²à¸‡" +msgstr "สะท้à¸à¸™à¸‹à¹‰à¸²à¸¢à¸‚วา" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Mirror Y" -msgstr "สะท้à¸à¸™à¸‹à¹‰à¸²à¸¢à¸‚วา" +msgstr "สะท้à¸à¸™à¸šà¸™à¸¥à¹ˆà¸²à¸‡" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -5883,10 +5884,6 @@ msgid "Please choose an empty folder." msgstr "à¸à¸£à¸¸à¸“าเลืà¸à¸à¹‚ฟลเดà¸à¸£à¹Œà¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸²" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "à¸à¸£à¸¸à¸“าเลืà¸à¸à¹‚ฟลเดà¸à¸£à¹Œà¸—ี่ไม่มีไฟล์ 'project.godot'" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "นำเข้าโปรเจà¸à¸•à¹Œà¹à¸¥à¹‰à¸§" @@ -5907,8 +5904,11 @@ msgid "Invalid project path (changed anything?)." msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¹‚ปรเจà¸à¸•à¹Œà¸œà¸´à¸”พลาด (ได้à¹à¸à¹‰à¹„ขà¸à¸°à¹„รไปหรืà¸à¹„ม่?)" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "ไม่พบไฟล์ project.godot" +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" +"โหลดไฟล์ project.godot ในโฟลเดà¸à¸£à¹Œà¹‚ปรเจà¸à¸•à¹Œà¹„ม่ได้ (ข้à¸à¸œà¸´à¸”พลาด %d) ไฟล์à¸à¸²à¸ˆà¸ªà¸¹à¸à¸«à¸²à¸¢à¸«à¸£à¸·à¸à¹€à¸ªà¸µà¸¢à¸«à¸²à¸¢" #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -5927,10 +5927,6 @@ msgid "Rename Project" msgstr "เปลี่ยนชื่à¸à¹‚ปรเจà¸à¸•à¹Œ" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "ไม่พบไฟล์ project.godot" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "โปรเจà¸à¸•à¹Œà¹ƒà¸«à¸¡à¹ˆ" @@ -6343,11 +6339,11 @@ msgstr "รีซà¸à¸£à¹Œà¸ª:" #: editor/project_settings_editor.cpp msgid "Remaps by Locale:" -msgstr "à¹à¸—นที่ตามท้à¸à¸‡à¸–ิ่น:" +msgstr "à¹à¸—นที่ตามภูมิภาค:" #: editor/project_settings_editor.cpp msgid "Locale" -msgstr "ท้à¸à¸‡à¸–ิ่น" +msgstr "ภูมิภาค" #: editor/project_settings_editor.cpp msgid "Locales Filter" @@ -6626,10 +6622,6 @@ msgstr "รีซà¸à¸£à¹Œà¸ªà¸¢à¹ˆà¸à¸¢" msgid "Clear Inheritance" msgstr "ลบà¸à¸²à¸£à¸ªà¸·à¸šà¸—à¸à¸”" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "เปิดในโปรà¹à¸à¸£à¸¡à¹à¸à¹‰à¹„ข" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "ลบโหนด" @@ -6745,10 +6737,6 @@ msgstr "" "คลิà¸à¹€à¸žà¸·à¹ˆà¸à¹à¸ªà¸”งà¹à¸œà¸‡à¸à¸¥à¸¸à¹ˆà¸¡" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "à¸à¸´à¸™à¸ªà¹à¸•à¸™à¸‹à¹Œ:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "เปิดสคริปต์" @@ -7175,32 +7163,44 @@ msgid "Object can't provide a length." msgstr "ไม่สามารถบà¸à¸à¸„วามยาวขà¸à¸‡à¸§à¸±à¸•à¸–ุได้" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "ลบที่เลืà¸à¸à¹ƒà¸™ GridMap" +msgid "Next Plane" +msgstr "ระนาบถัดไป" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "ทำซ้ำใน GridMap" +msgid "Previous Plane" +msgstr "ระนาบà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "ระนาบ:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "ไปชั้นบน" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "ไปชั้นล่าง" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "ชั้น:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "จำà¸à¸±à¸”ด้วยเส้นตาราง" +msgid "GridMap Delete Selection" +msgstr "ลบที่เลืà¸à¸à¹ƒà¸™ GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "บังคับà¹à¸™à¸§à¸•à¸²à¸£à¸²à¸‡" +msgid "GridMap Duplicate Selection" +msgstr "ทำซ้ำใน GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "ไปชั้นล่าง" +msgid "Grid Map" +msgstr "จำà¸à¸±à¸”ด้วยเส้นตาราง" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "ไปชั้นบน" +msgid "Snap View" +msgstr "บังคับà¹à¸™à¸§à¸•à¸²à¸£à¸²à¸‡" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7307,6 +7307,10 @@ msgid "Mono" msgstr "โมโน" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "เà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸à¸²à¸£à¸ªà¸™à¸±à¸šà¸ªà¸™à¸¸à¸™ C#" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "สร้าง C# solution" @@ -7322,6 +7326,10 @@ msgstr "Build โปรเจà¸à¸•à¹Œ" msgid "Warnings" msgstr "คำเตืà¸à¸™" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7837,6 +7845,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin ต้à¸à¸‡à¸¡à¸µ ARVRCamera เป็นโหนดลูà¸" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "%d%%" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "(เหลืà¸à¸à¸µà¸: %d:%02d วิ)" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "วางà¹à¸™à¸§ meshes: " @@ -8018,6 +8034,23 @@ msgstr "ผิดพลาดขณะโหลดฟà¸à¸™à¸•à¹Œ" msgid "Invalid font size." msgstr "ขนาดฟà¸à¸™à¸•à¹Œà¸œà¸´à¸”พลาด" +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "รูปà¹à¸šà¸šà¸‚à¸à¸‡ version.txt ในà¹à¸¡à¹ˆà¹à¸šà¸šà¹„ม่ถูà¸à¸•à¹‰à¸à¸‡ หมายเลขรุ่น revision ต้à¸à¸‡à¹ƒà¸Šà¹‰à¸£à¸°à¸šà¸¸à¹„ด้" + +#~ msgid "Can't write file." +#~ msgstr "เขียนไฟล์ไม่ได้" + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "à¸à¸£à¸¸à¸“าเลืà¸à¸à¹‚ฟลเดà¸à¸£à¹Œà¸—ี่ไม่มีไฟล์ 'project.godot'" + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "ไม่พบไฟล์ project.godot" + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "ไม่พบไฟล์ project.godot" + #~ msgid "Next" #~ msgstr "ต่à¸à¹„ป" diff --git a/editor/translations/tr.po b/editor/translations/tr.po index 934077d896..bb485dc603 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -2453,14 +2453,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Åžablonların içinde geçersiz version.txt formatı." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Åžablonların içinde geçersiz version.txt formatı. Revizyon geçerli bir " -"tanımlayıcı deÄŸil." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Åžablonların içinde version.txt bulunamadı." @@ -2515,10 +2507,6 @@ msgid "Failed:" msgstr "BaÅŸarısız:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Dosyaya yazılamıyor." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Ä°ndirme Tamamlandı." @@ -3704,15 +3692,15 @@ msgid "Show Grid" msgstr "Izgarayı Göster" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Yardımcıları Göster" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Cetvelleri göster" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Kılavuzları göster" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4539,6 +4527,22 @@ msgid "Resource clipboard is empty!" msgstr "Kaynak panosu boÅŸ!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Düzenleyicide Aç" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "Örnek:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Tür:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Kaynak Yükle" @@ -4825,10 +4829,6 @@ msgid "Toggle Comment" msgstr "Yorumu Aç / Kapat" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "AÅŸağıya EÅŸle" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "Satırı Katla/Aç" @@ -4841,6 +4841,10 @@ msgid "Unfold All Lines" msgstr "Tüm Satırları GeniÅŸlet" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "AÅŸağıya EÅŸle" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "Simgeyi Tamamla" @@ -5684,11 +5688,6 @@ msgstr "Sekme 2" msgid "Tab 3" msgstr "Sekme 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Tür:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Veri Türü:" @@ -5956,10 +5955,6 @@ msgid "Please choose an empty folder." msgstr "Lütfen boÅŸ bir klasör seçin." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "Lütfen 'proje.godot' dosyası içermeyen bir klasör seçin." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "İçe Aktarılan Proje" @@ -5980,8 +5975,11 @@ msgid "Invalid project path (changed anything?)." msgstr "Geçersiz proje yolu (bir ÅŸey deÄŸiÅŸti mi?)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "Proje yolunda proje.godot alınamadı." +#, fuzzy +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "proje yolundaki proje.godot düzenlenemedi." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -6000,10 +5998,6 @@ msgid "Rename Project" msgstr "Projeyi Yeniden Adlandır" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "Proje yolunda proje.godot alınamadı." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Yeni Oyun Projesi" @@ -6706,10 +6700,6 @@ msgstr "Alt Kaynaklar" msgid "Clear Inheritance" msgstr "Kalıtı Temizle" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Düzenleyicide Aç" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Düğümleri Sil" @@ -6827,10 +6817,6 @@ msgstr "" "Gruplar dokunu göstermek için tıkla." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "Örnek:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Betik Aç" @@ -7258,32 +7244,46 @@ msgid "Object can't provide a length." msgstr "Nesne bir uzunluk saÄŸlayamaz." #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "IzgaraHaritası Seçimi Sil" +#, fuzzy +msgid "Next Plane" +msgstr "Sonraki sekme" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "IzgaraHaritası Seçimi ÇoÄŸalt" +#, fuzzy +msgid "Previous Plane" +msgstr "Önceki sekme" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "Sonraki Zemin" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Önceki Zemin" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "Zemin:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "Izgara Haritası" +msgid "GridMap Delete Selection" +msgstr "IzgaraHaritası Seçimi Sil" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "Yapışma Görünümü" +msgid "GridMap Duplicate Selection" +msgstr "IzgaraHaritası Seçimi ÇoÄŸalt" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "Önceki Zemin" +msgid "Grid Map" +msgstr "Izgara Haritası" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "Sonraki Zemin" +msgid "Snap View" +msgstr "Yapışma Görünümü" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7390,6 +7390,10 @@ msgid "Mono" msgstr "Tekli" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "C# Çözümü oluÅŸtur" @@ -7405,6 +7409,10 @@ msgstr "Projeyi Ä°nÅŸa et" msgid "Warnings" msgstr "Uyarılar" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7955,6 +7963,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin bir ARVRCamera çocuk düğümü gerektirir" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "Örüntüler Haritalanıyor: " @@ -8155,6 +8171,25 @@ msgstr "Yazıtipi yükleme hatası." msgid "Invalid font size." msgstr "Geçersiz yazıtipi boyutu." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Åžablonların içinde geçersiz version.txt formatı. Revizyon geçerli bir " +#~ "tanımlayıcı deÄŸil." + +#~ msgid "Can't write file." +#~ msgstr "Dosyaya yazılamıyor." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "Lütfen 'proje.godot' dosyası içermeyen bir klasör seçin." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "Proje yolunda proje.godot alınamadı." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "Proje yolunda proje.godot alınamadı." + #~ msgid "Next" #~ msgstr "Sonraki" diff --git a/editor/translations/uk.po b/editor/translations/uk.po index d01686aec4..685812f2d4 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" -"PO-Revision-Date: 2018-01-24 17:51+0000\n" +"PO-Revision-Date: 2018-02-22 18:08+0000\n" "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" @@ -22,7 +22,7 @@ msgstr "" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 2.19-dev\n" +"X-Generator: Weblate 2.20-dev\n" #: editor/animation_editor.cpp msgid "Disabled" @@ -2456,14 +2456,6 @@ msgid "Invalid version.txt format inside templates." msgstr "Ðеправильний формат version.txt у шаблонах." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" -"Ðеправильний формат version.txt у шаблонах. Ідентифікатор ревізії не Ñ” " -"дійÑним." - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "Файл version.txt не знайдено у шаблонах." @@ -2518,10 +2510,6 @@ msgid "Failed:" msgstr "Ðе вдалоÑÑ:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати файл." - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð¾." @@ -3708,15 +3696,15 @@ msgid "Show Grid" msgstr "Показати Ñітку" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "Показати помічники" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "Показати лінійки" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "Показати напрÑмні" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4545,6 +4533,22 @@ msgid "Resource clipboard is empty!" msgstr "Ð’ буфері обміну немає реÑурÑу!" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "Відкрити в редакторі" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "ЕкземплÑÑ€:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "Тип:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "Завантажити реÑурÑ" @@ -4831,10 +4835,6 @@ msgid "Toggle Comment" msgstr "Перемкнути коментар" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "Клонувати вниз" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "Згорнути/розгорнути Ñ€Ñдок" @@ -4847,6 +4847,10 @@ msgid "Unfold All Lines" msgstr "Розгорнути вÑÑ– Ñ€Ñдки" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "Клонувати вниз" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "Завершити Ñимвол" @@ -5690,11 +5694,6 @@ msgstr "Вкладка 2" msgid "Tab 3" msgstr "Вкладка 3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "Тип:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "Тип даних:" @@ -5964,10 +5963,6 @@ msgid "Please choose an empty folder." msgstr "Будь лаÑка, виберіть порожню теку." #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "Будь лаÑка, виберіть теку, у Ñкій не міÑтитьÑÑ Ñ„Ð°Ð¹Ð»Ð° «project.godot»." - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "Імпортований проект" @@ -5988,8 +5983,12 @@ msgid "Invalid project path (changed anything?)." msgstr "Ðекоректний шлÑÑ… до проекту (щоÑÑŒ змінилоÑÑ?)." #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ project.godot з каталогу проекту." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "" +"Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ project.godot у каталозі проекту (помилка %d). " +"Можливо, файл вилучено або пошкоджено." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -6008,10 +6007,6 @@ msgid "Rename Project" msgstr "Перейменувати проект" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ project.godot у каталозі проекту." - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "Ðовий проект гри" @@ -6716,10 +6711,6 @@ msgstr "ПідреÑурÑи" msgid "Clear Inheritance" msgstr "УÑунути уÑпадкуваннÑ" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "Відкрити в редакторі" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "Вилучити вузли" @@ -6837,10 +6828,6 @@ msgstr "" "Клацніть, щоб переглÑнути панель груп." #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "ЕкземплÑÑ€:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "Відкрити Ñкрипт" @@ -7270,32 +7257,44 @@ msgid "Object can't provide a length." msgstr "Об'єкт не може надавати довжину." #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "Ð’Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾Ð³Ð¾ GridMap" +msgid "Next Plane" +msgstr "ÐаÑтупна площина" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "Ð”ÑƒÐ±Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾Ð³Ð¾ GridMap" +msgid "Previous Plane" +msgstr "ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ð¿Ð»Ð¾Ñ‰Ð¸Ð½Ð°" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "Площина:" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "ÐаÑтупний поверх" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "Попередній поверх" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "Поверх:" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" -msgstr "Карта Ñітки" +msgid "GridMap Delete Selection" +msgstr "Ð’Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾Ð³Ð¾ GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "Миттєвий переглÑд" +msgid "GridMap Duplicate Selection" +msgstr "Ð”ÑƒÐ±Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾Ð³Ð¾ GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" -msgstr "Попередній поверх" +msgid "Grid Map" +msgstr "Карта Ñітки" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "ÐаÑтупний поверх" +msgid "Snap View" +msgstr "Миттєвий переглÑд" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7402,6 +7401,10 @@ msgid "Mono" msgstr "Моно" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "Про підтримку C#" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "Створити розв'Ñзок C#" @@ -7417,6 +7420,10 @@ msgstr "Зібрати проект" msgid "Warnings" msgstr "ПопередженнÑ" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7968,6 +7975,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin повинен мати дочірній вузол ARVRCamera" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "%d%%" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "(ЛишилоÑÑ Ñ‡Ð°Ñу: %d:%02d Ñ)" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "Побудова Ñітки: " @@ -8170,6 +8185,26 @@ msgstr "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÑˆÑ€Ð¸Ñ„Ñ‚Ñƒ." msgid "Invalid font size." msgstr "Ðекоректний розмір шрифту." +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "" +#~ "Ðеправильний формат version.txt у шаблонах. Ідентифікатор ревізії не Ñ” " +#~ "дійÑним." + +#~ msgid "Can't write file." +#~ msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати файл." + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "" +#~ "Будь лаÑка, виберіть теку, у Ñкій не міÑтитьÑÑ Ñ„Ð°Ð¹Ð»Ð° «project.godot»." + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ project.godot з каталогу проекту." + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ project.godot у каталозі проекту." + #~ msgid "Next" #~ msgstr "Далі" diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index 9fae520b55..96fbfbeee6 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -2377,12 +2377,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2435,11 +2429,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -#, fuzzy -msgid "Can't write file." -msgstr "سب سکریپشن بنائیں" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3610,15 +3599,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4449,6 +4438,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4732,10 +4737,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "" @@ -4748,6 +4749,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5595,11 +5600,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5860,10 +5860,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5885,7 +5881,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5906,10 +5904,6 @@ msgid "Rename Project" msgstr ".تمام کا انتخاب" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6601,10 +6595,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6717,10 +6707,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "سب سکریپشن بنائیں" @@ -7152,32 +7138,44 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "GridMap Delete Selection" -msgstr ".تمام کا انتخاب" +msgid "Next Plane" +msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +msgid "Previous Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Delete Selection" +msgstr ".تمام کا انتخاب" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "GridMap Duplicate Selection" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7286,6 +7284,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "سب سکریپشن بنائیں" @@ -7302,6 +7304,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7806,6 +7812,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -7967,5 +7981,9 @@ msgstr "" msgid "Invalid font size." msgstr "" +#, fuzzy +#~ msgid "Can't write file." +#~ msgstr "سب سکریپشن بنائیں" + #~ msgid "Samples" #~ msgstr "نمونے" diff --git a/editor/translations/vi.po b/editor/translations/vi.po index 018883dc91..c39ccc4db9 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -2368,12 +2368,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2426,10 +2420,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3594,15 +3584,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4425,6 +4415,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4707,10 +4713,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "" @@ -4723,6 +4725,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5563,11 +5569,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5827,10 +5828,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5851,7 +5848,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5871,10 +5870,6 @@ msgid "Rename Project" msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6564,10 +6559,6 @@ msgstr "" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6677,10 +6668,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "" @@ -7103,11 +7090,24 @@ msgid "Object can't provide a length." msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" +msgid "Next Plane" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" +#, fuzzy +msgid "Previous Plane" +msgstr "ThÆ° mục trÆ°á»›c" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7115,19 +7115,19 @@ msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "GridMap Delete Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "GridMap Duplicate Selection" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Grid Map" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7235,6 +7235,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7250,6 +7254,10 @@ msgstr "" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7749,6 +7757,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index debb1d60f3..9c55ece6db 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -3,6 +3,8 @@ # Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) # This file is distributed under the same license as the Godot source code. # +# 360119124 <360119124@qq.com>, 2018. +# æŸ æª¬æ€æ‰‹ <lemonkiller@gmail.com>, 2018. # 纯æ´çš„å蛋 <tqj.zyy@gmail.com>, 2016. # å¤æœˆè“风 <trlanfeng@foxmail.com>, 2016. # å´äº®å¼Ÿ <wu@liangdi.me>, 2017. @@ -23,8 +25,8 @@ msgid "" msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2018-01-20 12:54+0000\n" -"Last-Translator: Geequlim <geequlim@gmail.com>\n" +"PO-Revision-Date: 2018-02-03 05:35+0000\n" +"Last-Translator: 360119124 <360119124@qq.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" "Language: zh_CN\n" @@ -48,11 +50,11 @@ msgstr "修改动画关键帧的时间" #: editor/animation_editor.cpp msgid "Anim Change Transition" -msgstr "动画å˜åŒ–过渡" +msgstr "修改动画过渡方å¼" #: editor/animation_editor.cpp msgid "Anim Change Transform" -msgstr "修改å˜æ¢" +msgstr "修改动画å˜æ¢" #: editor/animation_editor.cpp msgid "Anim Change Keyframe Value" @@ -100,7 +102,7 @@ msgstr "轨é“修改为值模å¼" #: editor/animation_editor.cpp msgid "Anim Track Change Wrap Mode" -msgstr "轨é“修改为包装模å¼" +msgstr "轨é“修改为包围模å¼" #: editor/animation_editor.cpp msgid "Edit Node Curve" @@ -108,7 +110,7 @@ msgstr "编辑节点曲线" #: editor/animation_editor.cpp msgid "Edit Selection Curve" -msgstr "编辑选项曲线" +msgstr "编辑所选曲线" #: editor/animation_editor.cpp msgid "Anim Delete Keys" @@ -133,7 +135,7 @@ msgstr "è¿žç»" #: editor/animation_editor.cpp msgid "Discrete" -msgstr "分离" +msgstr "离散" #: editor/animation_editor.cpp msgid "Trigger" @@ -198,7 +200,7 @@ msgstr "优化动画" #: editor/animation_editor.cpp msgid "Clean-Up Animation" -msgstr "清ç†åŠ¨ç”»" +msgstr "清空动画" #: editor/animation_editor.cpp msgid "Create NEW track for %s and insert key?" @@ -222,7 +224,7 @@ msgstr "创建|æ’入动画" #: editor/animation_editor.cpp msgid "Anim Insert Track & Key" -msgstr "创建|æ’å…¥ 轨é“和关键帧" +msgstr "æ’入轨é“和关键帧" #: editor/animation_editor.cpp msgid "Anim Insert Key" @@ -246,11 +248,11 @@ msgstr "æ’入动画" #: editor/animation_editor.cpp msgid "Anim Scale Keys" -msgstr "缩放键" +msgstr "缩放关键帧" #: editor/animation_editor.cpp msgid "Anim Add Call Track" -msgstr "æ·»åŠ å›žè°ƒè½¨é“" +msgstr "æ·»åŠ è°ƒç”¨è½¨é“" #: editor/animation_editor.cpp msgid "Animation zoom." @@ -298,11 +300,11 @@ msgstr "轨é“工具" #: editor/animation_editor.cpp msgid "Enable editing of individual keys by clicking them." -msgstr "å…许通过å•å‡»å¯ç”¨å„个键的编辑。" +msgstr "å…许通过å•å‡»ç¼–辑å„个关键帧。" #: editor/animation_editor.cpp msgid "Anim. Optimizer" -msgstr "优化动画" +msgstr "动画优化器" #: editor/animation_editor.cpp msgid "Max. Linear Error:" @@ -310,11 +312,11 @@ msgstr "最大线性错误:" #: editor/animation_editor.cpp msgid "Max. Angular Error:" -msgstr "最大角错误:" +msgstr "最大角度错误:" #: editor/animation_editor.cpp msgid "Max Optimizable Angle:" -msgstr "调整最大的角度:" +msgstr "调整最大的å¯ä¼˜åŒ–角度:" #: editor/animation_editor.cpp msgid "Optimize" @@ -338,7 +340,7 @@ msgstr "缩放比率:" #: editor/animation_editor.cpp msgid "Call Functions in Which Node?" -msgstr "在那个节点ä¸è°ƒç”¨å‡½æ•°ï¼Ÿ" +msgstr "在哪个节点ä¸è°ƒç”¨å‡½æ•°ï¼Ÿ" #: editor/animation_editor.cpp msgid "Remove invalid keys" @@ -358,7 +360,7 @@ msgstr "清除所有动画å—ï¼ˆæ— æ³•æ’¤é”€ï¼ï¼‰" #: editor/animation_editor.cpp msgid "Clean-Up" -msgstr "清ç†" +msgstr "清空" #: editor/array_property_edit.cpp msgid "Resize Array" @@ -430,13 +432,13 @@ msgstr "列:" #: editor/connections_dialog.cpp msgid "Method in target Node must be specified!" -msgstr "必须设置方法的对象节点ï¼" +msgstr "å¿…é¡»æŒ‡å®šç›®æ ‡èŠ‚ç‚¹çš„æ–¹æ³•ï¼" #: editor/connections_dialog.cpp msgid "" "Target method not found! Specify a valid method or attach a script to target " "Node." -msgstr "找ä¸åˆ°ç›®æ ‡æ–¹æ³•ï¼ æŒ‡å®šä¸€ä¸ªæœ‰æ•ˆçš„æ–¹æ³•æˆ–æŠŠè„šæœ¬é™„åŠ åˆ°ç›®æ ‡èŠ‚ç‚¹ã€‚" +msgstr "找ä¸åˆ°ç›®æ ‡æ–¹æ³•ï¼ è¯·æŒ‡å®šä¸€ä¸ªæœ‰æ•ˆçš„æ–¹æ³•æˆ–æŠŠè„šæœ¬é™„åŠ åˆ°ç›®æ ‡èŠ‚ç‚¹ã€‚" #: editor/connections_dialog.cpp msgid "Connect To Node:" @@ -1075,7 +1077,7 @@ msgstr "[空]" #: editor/editor_data.cpp msgid "[unsaved]" -msgstr "[ä½ä¿å˜]" +msgstr "[未ä¿å˜]" #: editor/editor_dir_dialog.cpp msgid "Please select a base directory first" @@ -1336,8 +1338,8 @@ msgid "" "$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/" "url][/color]." msgstr "" -"暂时没有æ¤ç±»åž‹çš„说明。请帮通过[color=$color][url=$url] 补充文档或æ交请求 [/" -"url][/color]çš„æ–¹å¼å¸®åŠ©æˆ‘们完善文档!" +"当å‰æ²¡æœ‰æ¤ç±»åž‹çš„教程。请通过[color=$color][url=$url] 补充文档或æ交请求 [/" +"url][/color]çš„æ–¹å¼å¸®åŠ©æˆ‘们完善文档。" #: editor/editor_help.cpp msgid "Properties" @@ -1368,7 +1370,7 @@ msgid "" "There is currently no description for this method. Please help us by [color=" "$color][url=$url]contributing one[/url][/color]!" msgstr "" -"当å‰æ²¡æœ‰æ¤æ–¹æ³•çš„说明。请帮助我们通过 [color=$color] [url=$url] 贡献一个 [/" +"当å‰æ²¡æœ‰æ¤æ–¹æ³•çš„æ述。请帮助我们通过 [color=$color] [url=$url] 贡献一个 [/" "url][/color]!" #: editor/editor_help.cpp @@ -2338,7 +2340,7 @@ msgstr "" #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." -msgstr "在_run()æ–¹ä¸å¡«å†™æ‚¨çš„逻辑代ç 。" +msgstr "在_run()方法ä¸å¡«å†™æ‚¨çš„逻辑代ç 。" #: editor/editor_run_script.cpp msgid "There is an edited scene already." @@ -2417,12 +2419,6 @@ msgid "Invalid version.txt format inside templates." msgstr "模æ¿æ–‡ä»¶ä¸çš„version.txtä¸åˆæ³•ã€‚" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "模æ¿ä¸çš„ version.txtæ–‡ä»¶æ ¼å¼ä¸åˆæ³•ï¼Œæ— æ•ˆçš„ç‰ˆæœ¬æ ‡è¯†ç¬¦ã€‚" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "模æ¿ä¸æ²¡æœ‰æ‰¾åˆ°version.txt文件。" @@ -2475,10 +2471,6 @@ msgid "Failed:" msgstr "失败:" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "æ— æ³•å†™å…¥æ–‡ä»¶ã€‚" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "下载完æˆ" @@ -2488,11 +2480,11 @@ msgstr "请求链接错误: " #: editor/export_template_manager.cpp msgid "Connecting to Mirror.." -msgstr "æ£åœ¨è¿žæŽ¥é•œåƒ..." +msgstr "æ£åœ¨è¿žæŽ¥é•œåƒâ€¦â€¦" #: editor/export_template_manager.cpp msgid "Disconnected" -msgstr "链接已æ–å¼€" +msgstr "å·²æ–å¼€" #: editor/export_template_manager.cpp msgid "Resolving" @@ -2518,7 +2510,7 @@ msgstr "已连接" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Requesting.." -msgstr "æ£åœ¨è¯·æ±‚.." +msgstr "æ£åœ¨è¯·æ±‚……" #: editor/export_template_manager.cpp msgid "Downloading" @@ -3040,7 +3032,7 @@ msgstr "穿过" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Future" -msgstr "" +msgstr "未æ¥" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Depth" @@ -3650,15 +3642,15 @@ msgid "Show Grid" msgstr "æ˜¾ç¤ºç½‘æ ¼" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "显示辅助线" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "æ˜¾ç¤ºæ ‡å°º" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "æ˜¾ç¤ºæ ‡å°º " #: editor/plugins/canvas_item_editor_plugin.cpp @@ -3723,7 +3715,7 @@ msgstr "好的" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Cannot instantiate multiple nodes without root." -msgstr "" +msgstr "æ— æ³•å®žä¾‹åŒ–æ²¡æœ‰æ ¹çš„å¤šä¸ªèŠ‚ç‚¹ã€‚" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp @@ -3933,7 +3925,7 @@ msgstr "包å«çš„Meshä¸æ˜¯ArrayMesh类型。" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Unwrap failed, mesh may not be manifold?" -msgstr "" +msgstr "UV展开失败,å¯èƒ½è¯¥ç½‘æ ¼å¹¶éžæµå½¢ï¼Ÿ" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "No mesh to debug." @@ -3993,7 +3985,7 @@ msgstr "查看UV2" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Unwrap UV2 for Lightmap/AO" -msgstr "" +msgstr "ä¸ºå…‰ç…§æ˜ å°„/环境光é®è”½å±•å¼€UV2" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh" @@ -4486,6 +4478,22 @@ msgid "Resource clipboard is empty!" msgstr "资æºå‰ªåˆ‡æ¿ä¸æ— 内容ï¼" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "在编辑器ä¸æ‰“å¼€" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "实例:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "类型:" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "åŠ è½½èµ„æº" @@ -4771,10 +4779,6 @@ msgid "Toggle Comment" msgstr "切æ¢æ³¨é‡Š" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "æ‹·è´åˆ°ä¸‹ä¸€è¡Œ" - -#: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" msgstr "切æ¢å è¡Œ" @@ -4787,6 +4791,10 @@ msgid "Unfold All Lines" msgstr "å–消折å 所有行" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "æ‹·è´åˆ°ä¸‹ä¸€è¡Œ" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "代ç 补全" @@ -5630,11 +5638,6 @@ msgstr "分页2" msgid "Tab 3" msgstr "分页3" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "类型:" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "æ•°æ®ç±»åž‹:" @@ -5761,7 +5764,7 @@ msgstr "错误" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Autotiles" -msgstr "" +msgstr "智能瓦片" #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -5897,10 +5900,6 @@ msgid "Please choose an empty folder." msgstr "请选择一个空目录。" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "请选择一个ä¸åŒ…å«'project.godot'文件的文件夹。" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "已导入的项目" @@ -5921,8 +5920,11 @@ msgid "Invalid project path (changed anything?)." msgstr "项目路径éžæ³•ï¼ˆè¢«å¤–部修改?)。" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." -msgstr "æ— æ³•åœ¨é¡¹ç›®ç›®å½•ä¸‹æ‰¾åˆ°project.godot文件。" +#, fuzzy +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." +msgstr "æ— æ³•åœ¨é¡¹ç›®ç›®å½•ä¸‹ç¼–è¾‘project.godot文件。" #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." @@ -5941,10 +5943,6 @@ msgid "Rename Project" msgstr "é‡å‘½å项目" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "æ— æ³•åœ¨é¡¹ç›®ç›®å½•ä¸‹æ‰¾åˆ°project.godot文件。" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "新建游æˆé¡¹ç›®" @@ -6486,15 +6484,15 @@ msgstr "选择属性" #: editor/property_selector.cpp msgid "Select Virtual Method" -msgstr "选择虚拟方法 " +msgstr "选择虚方法" #: editor/property_selector.cpp msgid "Select Method" -msgstr "选择方å¼" +msgstr "选择方法" #: editor/pvrtc_compress.cpp msgid "Could not execute PVRTC tool:" -msgstr "æ— æ³•æ‰§è¡ŒPVPTC工具:" +msgstr "æ— æ³•æ‰§è¡ŒPVRTC工具:" #: editor/pvrtc_compress.cpp msgid "Can't load back converted image using PVRTC tool:" @@ -6641,10 +6639,6 @@ msgstr "å资æº" msgid "Clear Inheritance" msgstr "清除继承" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "在编辑器ä¸æ‰“å¼€" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "åˆ é™¤èŠ‚ç‚¹" @@ -6708,9 +6702,8 @@ msgid "Clear a script for the selected node." msgstr "清除选ä¸èŠ‚点的脚本。" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Remote" -msgstr "移除" +msgstr "远程" #: editor/scene_tree_dock.cpp msgid "Local" @@ -6761,10 +6754,6 @@ msgstr "" "å•å‡»æ˜¾ç¤ºåˆ†ç»„æ 。" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "实例:" - -#: editor/scene_tree_editor.cpp msgid "Open script" msgstr "打开脚本" @@ -7192,34 +7181,46 @@ msgid "Object can't provide a length." msgstr "å¯¹è±¡æ— æ³•æ供长度。" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Delete Selection" -msgstr "åˆ é™¤é€‰æ‹©çš„GridMap" +#, fuzzy +msgid "Next Plane" +msgstr "下一项" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "GridMap Duplicate Selection" -msgstr "å¤åˆ¶é€‰ä¸é¡¹" +#, fuzzy +msgid "Previous Plane" +msgstr "上一个目录" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Plane:" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Next Floor" +msgstr "下一层" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Previous Floor" +msgstr "上一个层" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" msgstr "层:" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "Grid Map" -msgstr "ç½‘æ ¼å¸é™„" +msgid "GridMap Delete Selection" +msgstr "åˆ é™¤é€‰æ‹©çš„GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" -msgstr "å¸é™„视图" +msgid "GridMap Duplicate Selection" +msgstr "å¤åˆ¶é€‰ä¸é¡¹" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy -msgid "Previous Floor" -msgstr "上一个目录" +msgid "Grid Map" +msgstr "ç½‘æ ¼æ˜ å°„" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" -msgstr "下一层" +msgid "Snap View" +msgstr "å¸é™„视图" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" @@ -7326,6 +7327,10 @@ msgid "Mono" msgstr "Mono" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "创建C#解决方案" @@ -7341,6 +7346,10 @@ msgstr "构建项目" msgid "Warnings" msgstr "è¦å‘Š" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7670,7 +7679,7 @@ msgstr "脚本ä¸æœªæ‰¾åˆ°VariableSet: " #: modules/visual_script/visual_script_nodes.cpp msgid "Custom node has no _step() method, can't process graph." -msgstr "自定义脚本节点ä¸åŒ…å«_step()方法,ä¸èƒ½ç”Ÿæˆå›¾ã€‚" +msgstr "自定义节点ä¸åŒ…å«_step()方法,ä¸èƒ½ç”Ÿæˆå›¾åƒã€‚" #: modules/visual_script/visual_script_nodes.cpp msgid "" @@ -7858,23 +7867,28 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "ARVROrigin 必须拥有 ARVRCamera å节点" #: scene/3d/baked_lightmap.cpp -#, fuzzy +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " -msgstr "æ£åœ¨ç»˜åˆ¶ç½‘æ ¼" +msgstr "æ£åœ¨ç»˜åˆ¶ç½‘æ ¼ï¼š " #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Plotting Lights:" -msgstr "æ£åœ¨ç»˜åˆ¶ç½‘æ ¼" +msgstr "æ£åœ¨ç»˜åˆ¶ç¯å…‰ï¼š" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp msgid "Finishing Plot" msgstr "æ£åœ¨å®Œæˆåˆ’分" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Lighting Meshes: " -msgstr "æ£åœ¨ç»˜åˆ¶ç½‘æ ¼" +msgstr "æ£åœ¨å¯¹ç½‘æ ¼è¿›è¡Œç…§æ˜Ž " #: scene/3d/collision_object.cpp msgid "" @@ -8045,6 +8059,23 @@ msgstr "åŠ è½½å—体出错。" msgid "Invalid font size." msgstr "å—体大å°éžæ³•ã€‚" +#~ msgid "" +#~ "Invalid version.txt format inside templates. Revision is not a valid " +#~ "identifier." +#~ msgstr "模æ¿ä¸çš„ version.txtæ–‡ä»¶æ ¼å¼ä¸åˆæ³•ï¼Œæ— æ•ˆçš„ç‰ˆæœ¬æ ‡è¯†ç¬¦ã€‚" + +#~ msgid "Can't write file." +#~ msgstr "æ— æ³•å†™å…¥æ–‡ä»¶ã€‚" + +#~ msgid "Please choose a folder that does not contain a 'project.godot' file." +#~ msgstr "请选择一个ä¸åŒ…å«'project.godot'文件的文件夹。" + +#~ msgid "Couldn't get project.godot in project path." +#~ msgstr "æ— æ³•åœ¨é¡¹ç›®ç›®å½•ä¸‹æ‰¾åˆ°project.godot文件。" + +#~ msgid "Couldn't get project.godot in the project path." +#~ msgstr "æ— æ³•åœ¨é¡¹ç›®ç›®å½•ä¸‹æ‰¾åˆ°project.godot文件。" + #~ msgid "Next" #~ msgstr "下一项" diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index 3b380305d0..6e2e5ac502 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -2520,12 +2520,6 @@ msgid "Invalid version.txt format inside templates." msgstr "無效的 version.txt æ ¼å¼ inside templates." #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp #, fuzzy msgid "No version.txt found inside templates." msgstr "找ä¸åˆ°version.txt inside templates." @@ -2583,11 +2577,6 @@ msgstr "失敗:" #: editor/export_template_manager.cpp #, fuzzy -msgid "Can't write file." -msgstr "無法新增資料夾" - -#: editor/export_template_manager.cpp -#, fuzzy msgid "Download Complete." msgstr "下載出ç¾éŒ¯èª¤" @@ -3792,15 +3781,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4637,6 +4626,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4930,10 +4935,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "跳到行" @@ -4947,6 +4948,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5805,11 +5810,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -6080,10 +6080,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -6105,7 +6101,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -6126,10 +6124,6 @@ msgid "Rename Project" msgstr "專案" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6837,10 +6831,6 @@ msgstr "資æº" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6955,10 +6945,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "下一個腳本" @@ -7400,32 +7386,46 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "刪除é¸ä¸æª”案" +msgid "Next Plane" +msgstr "下一個" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "複製 Selection" +msgid "Previous Plane" +msgstr "上一個tab" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +msgid "Previous Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Previous Floor" +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Delete Selection" +msgstr "刪除é¸ä¸æª”案" + +#: modules/gridmap/grid_map_editor_plugin.cpp +#, fuzzy +msgid "GridMap Duplicate Selection" +msgstr "複製 Selection" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7540,6 +7540,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp #, fuzzy msgid "Create C# solution" msgstr "縮放selection" @@ -7557,6 +7561,10 @@ msgstr "專案" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -8078,6 +8086,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" @@ -8240,6 +8256,10 @@ msgstr "載入å—形出ç¾éŒ¯èª¤" msgid "Invalid font size." msgstr "無效å—åž‹" +#, fuzzy +#~ msgid "Can't write file." +#~ msgstr "無法新增資料夾" + #~ msgid "Next" #~ msgstr "下一個" diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index abdbf6dc2b..2d67ef98c1 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -2400,12 +2400,6 @@ msgid "Invalid version.txt format inside templates." msgstr "" #: editor/export_template_manager.cpp -msgid "" -"Invalid version.txt format inside templates. Revision is not a valid " -"identifier." -msgstr "" - -#: editor/export_template_manager.cpp msgid "No version.txt found inside templates." msgstr "" @@ -2460,10 +2454,6 @@ msgid "Failed:" msgstr "" #: editor/export_template_manager.cpp -msgid "Can't write file." -msgstr "" - -#: editor/export_template_manager.cpp msgid "Download Complete." msgstr "" @@ -3650,15 +3640,15 @@ msgid "Show Grid" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show helpers" +msgid "Show Helpers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show rulers" +msgid "Show Rulers" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -msgid "Show guides" +msgid "Show Guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4492,6 +4482,22 @@ msgid "Resource clipboard is empty!" msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp +msgid "Open in Editor" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/scene_tree_editor.cpp +msgid "Instance:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp +#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp +#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp +msgid "Type:" +msgstr "" + +#: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Load Resource" msgstr "" @@ -4780,10 +4786,6 @@ msgid "Toggle Comment" msgstr "" #: editor/plugins/script_text_editor.cpp -msgid "Clone Down" -msgstr "" - -#: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Fold/Unfold Line" msgstr "å‰å¾€ç¬¬...è¡Œ" @@ -4797,6 +4799,10 @@ msgid "Unfold All Lines" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Clone Down" +msgstr "" + +#: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" msgstr "" @@ -5646,11 +5652,6 @@ msgstr "" msgid "Tab 3" msgstr "" -#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp -#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp -msgid "Type:" -msgstr "" - #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" msgstr "" @@ -5916,10 +5917,6 @@ msgid "Please choose an empty folder." msgstr "" #: editor/project_manager.cpp -msgid "Please choose a folder that does not contain a 'project.godot' file." -msgstr "" - -#: editor/project_manager.cpp msgid "Imported Project" msgstr "" @@ -5941,7 +5938,9 @@ msgid "Invalid project path (changed anything?)." msgstr "" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in project path." +msgid "" +"Couldn't load project.godot in project path (error %d). It may be missing or " +"corrupted." msgstr "" #: editor/project_manager.cpp @@ -5962,10 +5961,6 @@ msgid "Rename Project" msgstr "專案è¨å®š" #: editor/project_manager.cpp -msgid "Couldn't get project.godot in the project path." -msgstr "" - -#: editor/project_manager.cpp msgid "New Game Project" msgstr "" @@ -6664,10 +6659,6 @@ msgstr "複製資æº" msgid "Clear Inheritance" msgstr "" -#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -msgid "Open in Editor" -msgstr "" - #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" msgstr "" @@ -6779,10 +6770,6 @@ msgid "" msgstr "" #: editor/scene_tree_editor.cpp -msgid "Instance:" -msgstr "" - -#: editor/scene_tree_editor.cpp #, fuzzy msgid "Open script" msgstr "開啟最近å˜å–" @@ -7224,33 +7211,47 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Delete Selection" -msgstr "複製所é¸" +msgid "Next Plane" +msgstr "下個分é " #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "GridMap Duplicate Selection" -msgstr "複製所é¸" +msgid "Previous Plane" +msgstr "上個分é " #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Floor:" +msgid "Plane:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Grid Map" +msgid "Next Floor" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Snap View" +#, fuzzy +msgid "Previous Floor" +msgstr "上個分é " + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Floor:" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp #, fuzzy -msgid "Previous Floor" -msgstr "上個分é " +msgid "GridMap Delete Selection" +msgstr "複製所é¸" #: modules/gridmap/grid_map_editor_plugin.cpp -msgid "Next Floor" +#, fuzzy +msgid "GridMap Duplicate Selection" +msgstr "複製所é¸" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Grid Map" +msgstr "" + +#: modules/gridmap/grid_map_editor_plugin.cpp +msgid "Snap View" msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7363,6 +7364,10 @@ msgid "Mono" msgstr "" #: modules/mono/editor/godotsharp_editor.cpp +msgid "About C# support" +msgstr "" + +#: modules/mono/editor/godotsharp_editor.cpp msgid "Create C# solution" msgstr "" @@ -7379,6 +7384,10 @@ msgstr "專案è¨å®š" msgid "Warnings" msgstr "" +#: modules/mono/mono_gd/gd_mono_utils.cpp +msgid "End of inner exception stack trace" +msgstr "" + #: modules/visual_script/visual_script.cpp msgid "" "A node yielded without working memory, please read the docs on how to yield " @@ -7893,6 +7902,14 @@ msgid "ARVROrigin requires an ARVRCamera child node" msgstr "" #: scene/3d/baked_lightmap.cpp +msgid "%d%%" +msgstr "" + +#: scene/3d/baked_lightmap.cpp +msgid "(Time Left: %d:%02d s)" +msgstr "" + +#: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " msgstr "" diff --git a/main/SCsub b/main/SCsub index 5748bc38d2..e2bf03234f 100644 --- a/main/SCsub +++ b/main/SCsub @@ -2,71 +2,139 @@ Import('env') from compat import byte_to_str - +from collections import OrderedDict def make_splash(target, source, env): src = source[0].srcnode().abspath dst = target[0].srcnode().abspath - f = open(src, "rb") - g = open(dst, "w") - buf = f.read() + with open(src, "rb") as f: + buf = f.read() - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef BOOT_SPLASH_H\n") - g.write("#define BOOT_SPLASH_H\n") - g.write('static const Color boot_splash_bg_color = Color::html("#232323");\n') - g.write("static const unsigned char boot_splash_png[] = {\n") - for i in range(len(buf)): - g.write(byte_to_str(buf[i]) + ",\n") - g.write("};\n") - g.write("#endif") + with open(dst, "w") as g: + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef BOOT_SPLASH_H\n") + g.write("#define BOOT_SPLASH_H\n") + g.write('static const Color boot_splash_bg_color = Color::html("#232323");\n') + g.write("static const unsigned char boot_splash_png[] = {\n") + for i in range(len(buf)): + g.write(byte_to_str(buf[i]) + ",\n") + g.write("};\n") + g.write("#endif") def make_splash_editor(target, source, env): src = source[0].srcnode().abspath dst = target[0].srcnode().abspath - f = open(src, "rb") - g = open(dst, "w") - buf = f.read() - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef BOOT_SPLASH_EDITOR_H\n") - g.write("#define BOOT_SPLASH_EDITOR_H\n") - g.write('static const Color boot_splash_editor_bg_color = Color::html("#232323");\n') - g.write("static const unsigned char boot_splash_editor_png[] = {\n") - for i in range(len(buf)): - g.write(byte_to_str(buf[i]) + ",\n") - g.write("};\n") - g.write("#endif") + with open(src, "rb") as f: + buf = f.read() + with open(dst, "w") as g: + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef BOOT_SPLASH_EDITOR_H\n") + g.write("#define BOOT_SPLASH_EDITOR_H\n") + g.write('static const Color boot_splash_editor_bg_color = Color::html("#232323");\n') + g.write("static const unsigned char boot_splash_editor_png[] = {\n") + for i in range(len(buf)): + g.write(byte_to_str(buf[i]) + ",\n") + g.write("};\n") + g.write("#endif") def make_app_icon(target, source, env): src = source[0].srcnode().abspath dst = target[0].srcnode().abspath - f = open(src, "rb") - g = open(dst, "w") - buf = f.read() + with open(src, "rb") as f: + buf = f.read() - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef APP_ICON_H\n") - g.write("#define APP_ICON_H\n") - g.write("static const unsigned char app_icon_png[] = {\n") - for i in range(len(buf)): - g.write(byte_to_str(buf[i]) + ",\n") - g.write("};\n") - g.write("#endif") + with open(dst, "w") as g: + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef APP_ICON_H\n") + g.write("#define APP_ICON_H\n") + g.write("static const unsigned char app_icon_png[] = {\n") + for i in range(len(buf)): + g.write(byte_to_str(buf[i]) + ",\n") + g.write("};\n") + g.write("#endif") +def make_default_controller_mappings(target, source, env): + dst = target[0].srcnode().abspath + g = open(dst, "w") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#include \"default_controller_mappings.h\"\n") + g.write("#include \"typedefs.h\"\n") + + # ensure mappings have a consistent order + platform_mappings = OrderedDict() + for src in source: + src_path = src.srcnode().abspath + with open(src_path, "r") as f: + # read mapping file and skip header + mapping_file_lines = f.readlines()[2:] + + current_platform = None + for line in mapping_file_lines: + if not line: + continue + line = line.strip() + if len(line) == 0: + continue + if line[0] == "#": + current_platform = line[1:].strip() + if current_platform not in platform_mappings: + platform_mappings[current_platform] = {} + elif current_platform: + line_parts = line.split(",") + guid = line_parts[0] + if guid in platform_mappings[current_platform]: + g.write("// WARNING - DATABASE {} OVERWROTE PRIOR MAPPING: {} {}\n".format(src_path, current_platform, platform_mappings[current_platform][guid])) + valid_mapping = True + for input_map in line_parts[2:]: + if "+" in input_map or "-" in input_map or "~" in input_map: + g.write("// WARNING - DISCARDED UNSUPPORTED MAPPING TYPE FROM DATABASE {}: {} {}\n".format(src_path, current_platform, line)) + valid_mapping = False + break + if valid_mapping: + platform_mappings[current_platform][guid] = line + + platform_variables = { + "Linux": "#if X11_ENABLED", + "Windows": "#ifdef WINDOWS_ENABLED", + "Mac OS X": "#ifdef OSX_ENABLED", + "Android": "#if defined(__ANDROID__)", + "iOS": "#ifdef IPHONE_ENABLED", + "Javascript": "#ifdef JAVASCRIPT_ENABLED", + "UWP": "#ifdef UWP_ENABLED", + } + + g.write("const char* DefaultControllerMappings::mappings[] = {\n") + for platform, mappings in platform_mappings.items(): + variable = platform_variables[platform] + g.write("{}\n".format(variable)) + for mapping in mappings.values(): + g.write("\t\"{}\",\n".format(mapping)) + g.write("#endif\n") + + g.write("\tNULL\n};\n") + g.close() env.main_sources = [] env.add_source_files(env.main_sources, "*.cpp") +# order matters here. higher index controller database files write on top of lower index database files +controller_databases = ["#main/gamecontrollerdb.txt", "#main/gamecontrollerdb_205.txt", "#main/gamecontrollerdb_204.txt", "#main/godotcontrollerdb.txt"] + +env.Depends("#main/default_controller_mappings.gen.cpp", controller_databases) +env.Command("#main/default_controller_mappings.gen.cpp", controller_databases, make_default_controller_mappings) + +env.main_sources.append("#main/default_controller_mappings.gen.cpp") + Export('env') env.Depends("#main/splash.gen.h", "#main/splash.png") diff --git a/platform/javascript/power_javascript.h b/main/default_controller_mappings.h index c0c564aa60..6319b875eb 100644 --- a/platform/javascript/power_javascript.h +++ b/main/default_controller_mappings.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* power_javascript.h */ +/* default_controller_mappings.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,26 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PLATFORM_JAVASCRIPT_POWER_JAVASCRIPT_H_ -#define PLATFORM_JAVASCRIPT_POWER_JAVASCRIPT_H_ - -#include "os/os.h" - -class PowerJavascript { -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; - - bool UpdatePowerInfo(); +#ifndef DEFAULT_CONTROLLER_MAPPINGS_H +#define DEFAULT_CONTROLLER_MAPPINGS_H +class DefaultControllerMappings { public: - PowerJavascript(); - virtual ~PowerJavascript(); - - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); + static const char *mappings[]; }; -#endif /* PLATFORM_JAVASCRIPT_POWER_JAVASCRIPT_H_ */ +#endif // DEFAULT_CONTROLLER_MAPPINGS_H diff --git a/main/gamecontrollerdb.txt b/main/gamecontrollerdb.txt new file mode 100644 index 0000000000..80687bd037 --- /dev/null +++ b/main/gamecontrollerdb.txt @@ -0,0 +1,423 @@ +# Game Controller DB for SDL in 2.0.6 format +# Source: https://github.com/gabomdq/SDL_GameControllerDB + +# Windows +03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows, +03000000022000000090000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000203800000900000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, +03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, +030000008f0e00001200000000000000,Acme,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows, +03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows, +030000006b1400000055000000000000,bigben ps3padstreetnew,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +0300000066f700000500000000000000,BrutalLegendTest,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, +03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows, +03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Windows, +03000000a306000022f6000000000000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows, +03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +030000004f04000023b3000000000000,Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, +030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows, +03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows, +03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows, +030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +03000000ffff00000000000000000000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +03000000451300000010000000000000,Generic USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00005f00000000000000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00005e00000000000000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00004000000000000000,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00006e00000000000000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00006600000000000000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f0000ee00000000000000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00004d00000000000000,HORIPAD3 A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000250900000017000000000000,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows, +030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Windows, +03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000830500006020000000000000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows, +03000000b50700001403000000000000,IMPACT BLACK,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +030000006f0e00002401000000000000,INJUSTICE FightStick for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +03000000491900000204000000000000,Ipega PG-9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows, +030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000380700005082000000000000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008433000000000000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008483000000000000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b6,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008134000000000000,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008184000000000000,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008532000000000000,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000380700003888000000000000,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000380700001888000000000000,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000008305000031b0000000000000,MaxfireBlaze3,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows, +03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, +03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, +030000008f0e00001030000000000000,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows, +0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, +03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, +030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Windows, +03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows, +030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,leftx:h0.6,lefty:h0.12,rightshoulder:b5,rightstick:a2,righttrigger:b7,rightx:h0.9,righty:h0.4,start:b9,x:b2,y:b3,platform:Windows, +03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows, +03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, +030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000008f0e00007530000000000000,PS (R) Gamepad,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b1,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000e30500009605000000000000,PS to USB convert cable,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, +03000000100800000100000000000000,PS1 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +03000000100800000300000000000000,PS2 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows, +03000000888800000803000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, +03000000250900000500000000000000,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows, +03000000100000008200000000000000,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows, +03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, +03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows, +03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, +03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows, +03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00006a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00006b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00008a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00008b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows, +0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, +0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, +030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000006f0e00001e01000000000000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, +03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows, +03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,x:b0,y:b1,platform:Windows, +03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, +03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, +03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Windows, +03000000300f00001101000000000000,saitek rumble pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, +030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, +03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows, +030000008f0e00000800000000000000,SpeedLink Strike FX Wireless,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows, +03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +030000004f04000015b3000000000000,Thrustmaster Dual Analog 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, +030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows, +030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, +03000000666600000488000000000000,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, +03000000d90400000200000000000000,TwinShock PS2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +03000000380700006652000000000000,UnKnown,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, +03000000632500002305000000000000,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, +03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, + +# Mac OS X +03000000022000000090000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000102800000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X, +030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X, +03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X, +03000000790000000600000000000000,G-Shark GP-702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Mac OS X, +03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, +030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00005e00000000010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00006e00000000010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00006600000000010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000008f0e00001330000011010000,HuiJia SNES Controller,a:b4,b:b2,back:b16,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b12,rightshoulder:b14,start:b18,x:b6,y:b0,platform:Mac OS X, +03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X, +03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X, +030000006d04000016c2000000020000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000006d04000016c2000000030000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +03000000380700005032000000010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +03000000380700005082000000010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X, +0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X, +03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X, +03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, +030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Mac OS X, +030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, +030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X, +030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, +030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, +030000004c050000a00b000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +03000000321500000010000000010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, +03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, +030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X, +03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X, +030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, +030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000005e0400008e02000001000000,Steam Virtual GamePad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X, +03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X, +03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X, +03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X, +03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X, +030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X, +030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X, +03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, +03000000bd12000015d0000000010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, +03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X, +050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X, +050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X, +030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +03000000c6240000045d000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X, +030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X, +030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, + +# Linux +03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, +05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, +030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, +03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux, +03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux, +03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, +03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:a0,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:a3,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001f01000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys GamePad ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux, +030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +06000000adde0000efbe000002010000,Hidromancer Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, +03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux, +030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00005f00000011010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00005e00000011010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006700000001010000,HORIPAD ONE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux, +03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, +050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000b50700001503000010010000,impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux, +030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, +03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000015c2000010010000,Logitech Logitech Extreme 3D,a:b0,b:b4,back:b6,guide:b8,leftshoulder:b9,leftstick:h0.8,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:h0.2,start:b7,x:b2,y:b5,platform:Linux, +030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux, +05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700005082000011010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, +03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008084000011010000,Mad Catz fightstick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008433000011010000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008483000011010000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000062230000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000d102000001010000,Microsoft X-Box One pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000d102000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Linux, +050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, +05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000000d0500000308000010010000,Nostromo n45 Dual Analog Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux, +03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000005e0400000202000000010000,Old Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c0500006802000000800000,PS3 Controller (Bluetooth),a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c050000a00b000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000a00b000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000c405000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000cc09000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux, +030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux, +030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, +0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, +03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, +03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, +03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux, +03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux, +03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000ad1b000038f0000090040000,Street Fighter IV FightStick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux, +030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux, +03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux, +05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, +0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux, +03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux, +xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, + +# Android +64633436313965656664373634323364,Microsoft X-Box 360 pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android, +37336435666338653565313731303834,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +61363931656135336130663561616264,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, +05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android, +5477696e20555342204a6f7973746963,Twin USB Joystick,a:b22,b:b21,back:b28,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android, +34356136633366613530316338376136,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,x:b17,y:b2,platform:Android, + +# iOS +4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS, +4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS, +05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS,
\ No newline at end of file diff --git a/main/gamecontrollerdb_204.txt b/main/gamecontrollerdb_204.txt new file mode 100644 index 0000000000..7f3068d1b1 --- /dev/null +++ b/main/gamecontrollerdb_204.txt @@ -0,0 +1,269 @@ +# Game Controller DB for SDL in 2.0.4 format +# Source: https://github.com/gabomdq/SDL_GameControllerDB + +# Windows +02200090000000000000504944564944,8Bitdo NES30 PRO USB,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +20380900000000000000504944564944,8Bitdo NES30 PRO Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, +8f0e1200000000000000504944564944,Acme,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows, +341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +c0111352000000000000504944564944,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows, +d81d0b00000000000000504944564944,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows, +e8206058000000000000504944564944,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +5e048e02000000000000504944564944,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +791d0103000000000000504944564944,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +341a0108000000000000504944564944,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +0d0f8500000000000000504944564944,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +0d0f5e00000000000000504944564944,Fighting Commander 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:a3,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +0d0f5f00000000000000504944564944,Fighting Commander 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +0d0f8400000000000000504944564944,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +0d0f8700000000000000504944564944,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +0d0f8800000000000000504944564944,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, +0d0f2700000000000000504944564944,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +79000600000000000000504944564944,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows, +28040140000000000000504944564944,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +45130010000000000000504944564944,Generic USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +0d0f4900000000000000504944564944,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +d8140862000000000000504944564944,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, +0d0f4000000000000000504944564944,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, +0d0f6e00000000000000504944564944,HORIPAD 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +0d0fee00000000000000504944564944,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +0d0f4d00000000000000504944564944,HORIPAD3 A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +25090017000000000000504944564944,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows, +d81d0f00000000000000504944564944,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +d81d1000000000000000504944564944,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows, +6f0e2401000000000000504944564944,INJUSTICE FightStick for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +6d0418c2000000000000504944564944,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +38075032000000000000504944564944,Mad Catz FightPad PRO PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +38075082000000000000504944564944,Mad Catz FightPad PRO PS4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +38078433000000000000504944564944,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +38078483000000000000504944564944,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b6,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +38078134000000000000504944564944,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +38078184000000000000504944564944,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +38078034000000000000504944564944,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +38078084000000000000504944564944,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +38078532000000000000504944564944,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +38073888000000000000504944564944,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +38071888000000000000504944564944,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +25090128000000000000504944564944,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows, +79004318000000000000504944564944,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, +8f0e1030000000000000504944564944,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows, +2509e803000000000000504944564944,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, +79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +8f0e0d31000000000000504944564944,Multilaser JS071 USB,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +100801e5000000000000504944564944,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b9,platform:Windows, +bd1215d0000000000000504944564944,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows, +4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,leftx:h0.6,lefty:h0.12,rightshoulder:b5,rightstick:a2,righttrigger:b7,rightx:h0.9,righty:h0.4,start:b9,x:b2,y:b3,platform:Windows, +36280100000000000000504944564944,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b15,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b14,x:b1,y:b2,platform:Windows, +4d6963726f736f66742050432d6a6f79,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a5,righty:a4,x:b1,y:b2,platform:Windows, +120cf60e000000000000504944564944,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, +8f0e0300000000000000504944564944,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +10080100000000000000504944564944,PS1 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +10080300000000000000504944564944,PS2 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows, +88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, +25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows, +10008200000000000000504944564944,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +300f0011000000000000504944564944,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows, +300f1611000000000000504944564944,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, +222c0020000000000000504944564944,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows, +300f1210000000000000504944564944,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, +341a0104000000000000504944564944,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows, +222c0223000000000000504944564944,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +222c0023000000000000504944564944,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +0d0f1100000000000000504944564944,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +0d0f6a00000000000000504944564944,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +0d0f6b00000000000000504944564944,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +0d0f8a00000000000000504944564944,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +0d0f8b00000000000000504944564944,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +0d0f7000000000000000504944564944,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +0d0f2200000000000000504944564944,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, +00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, +6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +300f1201000000000000504944564944,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b9,rightx:a2,righty:a3,start:b4,x:b0,y:b1,platform:Windows, +300f1001000000000000504944564944,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +9b280500000000000000504944564944,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, +79001100000000000000504944564944,Sega Saturn Gamepad,a:b1,b:b2,leftshoulder:b6,lefttrigger:b3,leftx:a0,lefty:a4,rightshoulder:b7,righttrigger:b0,start:b8,x:b4,y:b5,platform:Windows, +4c05cc09000000000000504944564944,Sony DualShock 4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +4c05a00b000000000000504944564944,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +ff113133000000000000504944564944,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows, +4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, +4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows, +66660488000000000000504944564944,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, +38076652000000000000504944564944,UnKnown,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, +63252305000000000000504944564944,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +79001b18000000000000504944564944,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, + +# Mac OS X +10280000000000000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, +830500000000000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Mac OS X, +AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, +0d0f0000000000004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +0d0f0000000000006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X, +6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +2509000000000000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X, +79000000000000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X, +d814000000000000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, +8f0e0000000000000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X, +4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, +4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +891600000000000000fd000000000000,Razer Onza Tournament,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +79000000000000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, +81170000000000007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X, +b4040000000000000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X, +351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, +4c05000000000000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +4c05000000000000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +11010000000000002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X, +11010000000000001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X, +4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X, +4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X, +bd1200000000000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, +10080000000000000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X, +050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X, +050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X, +5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +5e04000000000000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +5e04000000000000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X, +5e04000000000000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, + +# Linux +05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, +030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b1,y:b3,platform:Linux, +0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:a0,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:a3,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001f01000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +03000000ff1100004133000010010000,GreenAsia Inc.USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +06000000adde0000efbe000002010000,Hidromancer Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, +03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux, +030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, +03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux, +030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, +03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000016c2000010010000,Logitech Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux, +05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, +03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000062230000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000dd02000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b9,platform:Linux, +050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux, +030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000790000001100000010010000,RetroLink Saturn Classic Controller,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, +0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, +03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, +03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux, +030000004c050000c405000011810000,Sony DualShock 4,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000cc09000000810000,Sony DualShock 4 (CUH-ZCT2U) (Bluetooth),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000cc09000011810000,Sony DualShock 4 (CUH-ZCT2U) (USB),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux, +030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux, +03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000d102000001010000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux, +xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, + +# Android +4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, + +# iOS +4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS, +4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS,
\ No newline at end of file diff --git a/main/gamecontrollerdb_205.txt b/main/gamecontrollerdb_205.txt new file mode 100644 index 0000000000..4c3eae623c --- /dev/null +++ b/main/gamecontrollerdb_205.txt @@ -0,0 +1,337 @@ +# Game Controller DB for SDL in 2.0.5 format +# Source: https://github.com/gabomdq/SDL_GameControllerDB + +# Windows +xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +e8206058000000000000504944564944,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, +78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows, +6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +6d0418c2000000000000504944564944,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +4d6963726f736f66742050432d6a6f79,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a5,righty:a4,x:b1,y:b2,platform:Windows, +4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows, +341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows, +10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, +03000000ffff00000000000000000000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows, +03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000e30500009605000000000000,PS to USB convert cable,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, +03000000d90400000200000000000000,TwinShock PS2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows, +03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, +03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows, +03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows, +03000000b50700001403000000000000,IMPACT BLACK,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows, +03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, +03000000a30600000cff000000000000,Saitek P2500,a:b2,b:b3,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b9,rightx:a2,righty:a3,start:b4,x:b0,y:b1,platform:Windows, +03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, +03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, +030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, +030000008f0e00007530000000000000,PS (R) Gamepad,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b1,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000008f0e00001200000000000000,Acme,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows, +030000008f0e00001030000000000000,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows, +030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000008f0e00000800000000000000,SpeedLink Strike FX Wireless,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +03000000888800000803000000000000,PS3,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows, +03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows, +030000008305000031b0000000000000,MaxfireBlaze3,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, +03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +03000000790000001100000000000000,Sega Saturn Gamepad,a:b1,b:b2,leftshoulder:b6,lefttrigger:b3,leftx:a0,lefty:a4,rightshoulder:b7,righttrigger:b0,start:b8,x:b4,y:b5,platform:Windows, +03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows, +03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000006f0e00002401000000000000,INJUSTICE FightStick for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000006f0e00001e01000000000000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000006d04000019c2000000000000,Logitech Cordless RumblePad 2 USB,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000006d04000018c2000000000000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000006d04000016c2000000000000,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows, +030000006b1400000055000000000000,bigben ps3padstreetnew,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +0300000066f700000500000000000000,BrutalLegendTest,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, +03000000666600000488000000000000,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, +03000000632500002305000000000000,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000004f04000023b3000000000000,Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000004f04000015b3000000000000,Thrustmaster Dual Analog 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, +030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, +030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows, +030000004c050000cc09000000000000,Sony DualShock 4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows, +030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,leftx:h0.6,lefty:h0.12,rightshoulder:b5,rightstick:a2,righttrigger:b7,rightx:h0.9,righty:h0.4,start:b9,x:b2,y:b3,platform:Windows, +03000000491900000204000000000000,Ipega PG-9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000451300000010000000000000,Generic USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +03000000380700008532000000000000,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008483000000000000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b6,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008433000000000000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008184000000000000,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008134000000000000,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000380700006652000000000000,UnKnown,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, +03000000380700005082000000000000,Mad Catz FightPad PRO PS4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000380700005032000000000000,Mad Catz FightPad PRO PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000380700003888000000000000,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000380700001888000000000000,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b15,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b14,x:b1,y:b2,platform:Windows, +03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows, +03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows, +03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, +03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, +03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +03000000300f00001101000000000000,saitek rumble pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, +03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows, +03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows, +0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, +03000000250900000500000000000000,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows, +03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows, +03000000250900000017000000000000,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows, +03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows, +03000000203800000900000000000000,8Bitdo NES30 PRO Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, +03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, +03000000100800000300000000000000,PS2 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +030000001008000001e5000000000000,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b9,platform:Windows, +03000000100800000100000000000000,PS1 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, +03000000100000008200000000000000,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00008b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00008a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, +030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00006e00000000000000,HORIPAD 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00006b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00006a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00005f00000000000000,Fighting Commander 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00005e00000000000000,Fighting Commander 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:a3,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00004d00000000000000,HORIPAD3 A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00004000000000000000,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +03000000022000000090000000000000,8Bitdo NES30 PRO USB,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, +0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, +0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, + +# Mac OS X +830500000000000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, +351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, +11010000000000002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X, +11010000000000001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X, +10280000000000000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, +050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X, +050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X, +0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, +03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X, +03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, +03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X, +03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X, +030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X, +03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X, +03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X, +03000000790000000600000000000000,G-Shark GP-702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Mac OS X, +03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X, +030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X, +030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X, +030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X, +030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X, +030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, +0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X, +03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X, +030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, +030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X, + +# Linux +xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +06000000adde0000efbe000002010000,Hidromancer Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, +05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, +050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +050000004c050000cc09000000810000,Sony DualShock 4 (CUH-ZCT2U) (Bluetooth),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +050000004c0500006802000000810000,Sony PLAYSTATION(R)3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, +050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, +05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000ff1100004133000010010000,GreenAsia Inc.USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux, +03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, +03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux, +03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux, +03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux, +03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, +03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, +03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, +03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, +03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, +030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux, +030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, +030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, +03000000790000001100000010010000,RetroLink Saturn Classic Controller,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, +03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux, +03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux, +03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, +030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00001f01000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:a0,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:a3,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, +030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000016c2000010010000,Logitech Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux, +03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux, +03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +030000005e040000dd02000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000d102000001010000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000062230000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e0400000202000000010000,Old Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, +03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, +030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux, +030000004c050000cc09000011810000,Sony DualShock 4 (CUH-ZCT2U) (USB),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000c405000011810000,Sony DualShock 4,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +030000004c0500006802000011810000,Sony PLAYSTATION(R)3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, +030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, +03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008483000011010000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008433000011010000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008084000011010000,Mad Catz fightstick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, +03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, +03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b1,y:b3,platform:Linux, +03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, +03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b9,platform:Linux, +03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, +03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00006700000001010000,HORIPAD ONE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux, +0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, +0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, +0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, + +# Android +4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, + +# iOS +4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS, +4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS, diff --git a/main/godotcontrollerdb.txt b/main/godotcontrollerdb.txt new file mode 100644 index 0000000000..031a761f30 --- /dev/null +++ b/main/godotcontrollerdb.txt @@ -0,0 +1,38 @@ +# Game Controller DB for SDL in 2.0.6 format +# Source: https://github.com/godotengine/godot + +# Windows +9000318000000000000504944564944,Mayflash Wiimote PC Adapter,a:b2,b:h0.4,x:b0,y:b1,back:b4,start:b5,guide:b11,leftshoulder:b6,rightshoulder:b3,leftx:a0,lefty:a1,platform:Windows, +c911f055000000000000504944564944,GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +__XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpdown:b1,dpleft:b2,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Windows, + +# Linux +030000005e040000e302000003020000,Microsoft X-Box One Elite pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000006f0e00001302000000010000,Afterglow Gamepad for Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +05000000362800000100000004010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,platform:Windows, +030000005e0400001907000000010000,X360 Wireless Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:h0.8,lefttrigger:a2,x:b2,dpup:h0.1,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Windows, +030000005e0400008e02000001000000,Microsoft X-Box 360 pad,leftstick:b9,leftx:a0,lefty:a1,dpdown:h0.1,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:h0.2,lefttrigger:a2,x:b2,dpup:h0.4,back:b6,leftshoulder:b4,y:b3,a:b0,dpright:h0.8,righttrigger:a5,b:b1,platform:Windows, +03000000fd0500002a26000000010000,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b5,rightshoulder:b7,rightx:a2,start:b11,righty:a3,dpleft:h0.8,lefttrigger:b8,x:b0,dpup:h0.1,back:b10,leftstick:b2,leftshoulder:b6,y:b1,a:b3,dpright:h0.2,righttrigger:b9,b:b4,platform:Windows, +030000006f0e00002801000011010000,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b0,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:h0.2,righttrigger:b7,b:b2,platform:Windows, +030000000d0f00004d00000011010000,HORI Gem Pad 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows, + +# Android +4f5559412047616d6520436f6e74726f,OUYA Game Controller,leftx:a1,lefty:a3,dpdown:b12,rightstick:b8,rightshoulder:b10,rightx:a6,start:b-86,righty:a7,dpleft:b13,lefttrigger:b15,x:b2,dpup:b11,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:b14,righttrigger:b16,b:b1,platform:Windows, +Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Windows, +532e542e442e20496e74657261637420,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b25,rightshoulder:b27,rightx:a2,start:b31,righty:a3,dpleft:h0.8,lefttrigger:b28,x:b20,dpup:h0.1,back:b30,leftstick:b22,leftshoulder:b26,y:b21,a:b23,dpright:h0.2,righttrigger:b29,b:b24,platform:Windows, +506572666f726d616e63652044657369,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:h0.2,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,platform:Windows, +4d6963726f736f667420582d426f7820,Microsoft X-Box 360 pad,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Windows, +484f524920434f2e2c4c544420205041,Hori Gem Pad 3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:b15,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,platform:Windows, +47656e6572696320582d426f78207061,Logitech F-310,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a5,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a4,b:b1,platform:Windows, + +# Javascript +Default HTML5 Gamepad, Default Mapping,leftx:a0,lefty:a1,dpdown:b13,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:b14,lefttrigger:a6,x:b2,dpup:b12,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:b15,righttrigger:a7,b:b1,platform:Windows, +c2a94d6963726f736f66742058626f78,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,platform:Windows, +303534632d303563342d576972656c65,PS4 Controller USB/Win,leftx:a0,lefty:a1,dpdown:b15,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a5,lefttrigger:a3,x:b0,dpup:b14,dpleft:b16,dpright:b17,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,righttrigger:b7,b:b2,platform:Windows, +303534632d303563342d536f6e792043,PS4 Controller USB/Linux,leftx:a0,lefty:a1,dpdown:a7,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a5,dpleft:a6,lefttrigger:a3,x:b0,dpup:a7,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:a6,righttrigger:a4,b:b2,platform:Windows, +303534632d303236382d536f6e792050,PS3 Controller USB/Linux,leftx:a0,lefty:a1,dpdown:b6,rightstick:b2,rightshoulder:b11,rightx:a2,start:b3,righty:a3,dpleft:b7,lefttrigger:b8,x:b15,dpup:b4,back:b0,leftstick:b1,leftshoulder:b10,y:b12,a:b14,dpright:b5,righttrigger:b9,b:b13,platform:Windows, +303435652d303731392d58626f782033,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,platform:Windows, +303435652d303238652d4d6963726f73,Wired X360 Controller,leftx:a0,lefty:a1,dpdown:a7,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:a6,lefttrigger:a2,x:b2,dpup:a7,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:a6,righttrigger:a5,b:b1,platform:Windows, + +# UWP +__UWP_GAMEPAD__,Xbox Controller,a:b2,b:b3,x:b4,y:b5,start:b0,back:b1,leftstick:b12,rightstick:b13,leftshoulder:b10,rightshoulder:b11,dpup:b6,dpdown:b7,dpleft:b8,dpright:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Windows,
\ No newline at end of file diff --git a/main/input_default.cpp b/main/input_default.cpp index 5057c5f53a..c3bc83b2de 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -30,6 +30,7 @@ #include "input_default.h" +#include "default_controller_mappings.h" #include "input_map.h" #include "os/os.h" #include "scene/resources/texture.h" @@ -429,7 +430,7 @@ Point2 InputDefault::get_last_mouse_speed() const { int InputDefault::get_mouse_button_mask() const { - return mouse_button_mask; // do not trust OS implementaiton, should remove it - OS::get_singleton()->get_mouse_button_state(); + return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state(); } void InputDefault::warp_mouse_position(const Vector2 &p_to) { @@ -525,292 +526,6 @@ void InputDefault::set_mouse_in_window(bool p_in_window) { */ } -// from github.com/gabomdq/SDL_GameControllerDB -static const char *s_ControllerMappings[] = { -#ifdef WINDOWS_ENABLED - "00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "02200090000000000000504944564944,8Bitdo NES30 PRO USB,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", - "03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,", - "0d0f1100000000000000504944564944,REAL ARCADE PRO.3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,", - "0d0f2200000000000000504944564944,REAL ARCADE Pro.V3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "0d0f2700000000000000504944564944,FIGHTING STICK V3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,", - "0d0f4000000000000000504944564944,Hori Fighting Stick Mini 3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b5,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b4,righttrigger:b6,", - "0d0f4900000000000000504944564944,Hatsune Miku Sho Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "0d0f4d00000000000000504944564944,HORIPAD3 A,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "0d0f5e00000000000000504944564944,Fighting Commander 4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b5,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a4,righttrigger:a3,", - "0d0f5f00000000000000504944564944,Fighting Commander 4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "0d0f6a00000000000000504944564944,Real Arcade Pro.4,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,", - "0d0f6b00000000000000504944564944,Real Arcade Pro.4,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "0d0f6e00000000000000504944564944,HORIPAD 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "0d0f7000000000000000504944564944,REAL ARCADE PRO.4 VLX,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,", - "0d0f8400000000000000504944564944,Fighting Commander 5,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,", - "0d0f8500000000000000504944564944,Fighting Commander 2016 PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "0d0f8700000000000000504944564944,Fighting Stick mini 4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,", - "0d0f8800000000000000504944564944,Fighting Stick mini 4,a:b1,b:b2,x:b0,y:b3,back:b9,guide:b12,start:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,", - "0d0f8a00000000000000504944564944,Real Arcade Pro.4,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,", - "0d0f8b00000000000000504944564944,Real Arcade Pro.4,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "10008200000000000000504944564944,PS360+ v1.66,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:h0.4,lefttrigger:b6,righttrigger:b7,", - "10080100000000000000504944564944,PS1 USB,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,", - "100801e5000000000000504944564944,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,", - "10080300000000000000504944564944,PS2 USB,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a4,righty:a2,lefttrigger:b4,righttrigger:b5,", - "10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,y:b3,x:b4,start:b11,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,", - "120cf60e000000000000504944564944,P4 Wired Gamepad,a:b1,b:b2,x:b0,y:b3,back:b12,guide:b8,start:b9,leftshoulder:b5,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:h0.0,lefttrigger:b7,righttrigger:b6,", - "20380900000000000000504944564944,8Bitdo NES30 PRO Wireless,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", - "222c0020000000000000504944564944,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:a3,righttrigger:a4,", - "222c0023000000000000504944564944,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,x:b0,y:b3,back:b13,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", - "222c0223000000000000504944564944,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "25090017000000000000504944564944,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b5,rightshoulder:b7,leftx:a0,lefty:a1,lefttrigger:b4,righttrigger:b6,", - "25090128000000000000504944564944,Mayflash Arcade Stick,a:b1,b:b2,x:b5,y:b6,back:b8,start:b9,leftshoulder:b0,rightshoulder:b3,leftx:a0,lefty:a1,rightx:h0.4,righty:h0.0,lefttrigger:b4,righttrigger:b7,", - "25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,", - "2509e803000000000000504944564944,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "28040140000000000000504944564944,GamePad Pro USB,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,", - "300f0011000000000000504944564944,QanBa Arcade JoyStick 1008,x:b0,a:b1,b:b2,y:b3,back:b8,start:b10,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,", - "300f1001000000000000504944564944,Saitek P480 Rumble Pad,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,", - "300f1201000000000000504944564944,Saitek Dual Analog Pad,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,", - "300f1210000000000000504944564944,QanBa Joystick Plus,a:b0,b:b1,x:b2,y:b3,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,", - "300f1611000000000000504944564944,QanBa Arcade JoyStick 4018,a:b1,b:b2,x:b0,y:b3,back:b10,guide:b9,start:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,", - "341a0104000000000000504944564944,QanBa Joystick Q4RAF,a:b5,b:b6,x:b1,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b0,rightshoulder:b3,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,lefttrigger:b4,righttrigger:b7,", - "341a0108000000000000504944564944,EXEQ RF USB Gamepad 8206,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,leftstick:b8,rightstick:b7,back:b8,start:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "36280100000000000000504944564944,OUYA Controller,a:b0,b:b3,y:b2,x:b1,start:b14,guide:b15,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b8,dpleft:b10,dpdown:b9,dpright:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b12,righttrigger:b13,", - "38071888000000000000504944564944,MadCatz SFIV FightStick PS3,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b5,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b7,righttrigger:b6,", - "38073888000000000000504944564944,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "38075032000000000000504944564944,Mad Catz FightPad PRO PS3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "38075082000000000000504944564944,Mad Catz FightPad PRO PS4,x:b0,a:b1,b:b2,y:b3,back:b13,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,", - "38076652000000000000504944564944,UnKnown,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "38078034000000000000504944564944,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "38078084000000000000504944564944,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", - "38078134000000000000504944564944,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b7,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b4,", - "38078184000000000000504944564944,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b5,rightshoulder:b4,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a4,righttrigger:b7,", - "38078433000000000000504944564944,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,", - "38078483000000000000504944564944,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:b6,", - "38078532000000000000504944564944,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "45130010000000000000504944564944,Generic USB Joystick,a:b0,b:b1,x:b2,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,", - "4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftstick:a0,rightstick:a2,leftshoulder:a3,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:h0.6,lefty:h0.12,rightx:h0.9,righty:h0.4,lefttrigger:b6,righttrigger:b7,", - "4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", - "4c05a00b000000000000504944564944,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", - "4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "4c05cc09000000000000504944564944,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", - "4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", - "4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,", - "5e048e02000000000000504944564944,Controller (XBOX 360 For Windows),x:b2,a:b0,b:b1,y:b3,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,righttrigger:a2,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "63252305000000000000504944564944,USB Vibration Joystick (BM),x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "66660488000000000000504944564944,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:b12,dpdown:b14,dpleft:b15,dpright:b13,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,", - "6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "6d0418c2000000000000504944564944,Logitech RumblePad 2 USB,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,", - "6f0e2401000000000000504944564944,INJUSTICE FightStick for PS3,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2", - "79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "79000600000000000000504944564944,G-Shark GS-GP702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,", - "79001100000000000000504944564944,Sega Saturn Gamepad,a:b1,b:b2,x:b4,y:b5,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a4,lefttrigger:b3,righttrigger:b0,", - "79001b18000000000000504944564944,Venom Arcade Joystick,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b6,righttrigger:b7,", - "79004318000000000000504944564944,Mayflash GameCube Controller Adapter,a:b1,b:b2,x:b0,y:b3,back:b0,start:b9,guide:b0,leftshoulder:b4,rightshoulder:b7,leftstick:b0,rightstick:b0,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,", - "83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", - "88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,", - "8f0e0300000000000000504944564944,Piranha xtreme,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", - "8f0e0d31000000000000504944564944,Multilaser JS071 USB,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "8f0e1030000000000000504944564944,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,x:b3,y:b4,start:b9,leftshoulder:b6,rightshoulder:b2,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b5,righttrigger:b7,", - "8f0e1200000000000000504944564944,Acme,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", - "9000318000000000000504944564944,Mayflash Wiimote PC Adapter,a:b2,b:h0.4,x:b0,y:b1,back:b4,start:b5,guide:b11,leftshoulder:b6,rightshoulder:b3,leftx:a0,lefty:a1,", - "9b280500000000000000504944564944,Saturn_Adapter_2.0,a:b1,b:b2,x:b0,y:b3,start:b9,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,lefttrigger:b4,righttrigger:b5,", - "a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,y:b1,x:b0,start:b4,guide:b10,back:b5,leftstick:b8,rightstick:b9,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "bd1215d0000000000000504944564944,Nintendo Retrolink USB Super SNES Classic Controller,y:b0,b:b1,a:b2,x:b3,leftshoulder:b4,rightshoulder:b5,start:b9,back:b8,leftx:a0,lefty:a1,", - "c0111352000000000000504944564944,Battalife Joystick,x:b4,a:b6,b:b7,y:b5,back:b2,start:b3,leftshoulder:b0,rightshoulder:b1,leftx:a0,lefty:a1,", - "c911f055000000000000504944564944,GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", - "d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "d8140862000000000000504944564944,HitBox Edition Cthulhu+,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b5,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,lefttrigger:b4,righttrigger:b6,", - "d81d0b00000000000000504944564944,BUFFALO BSGP1601 Series ,x:b4,a:b5,b:b3,y:b2,back:b12,start:b13,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b6,rightshoulder:b9,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "d81d0f00000000000000504944564944,iBUFFALO BSGP1204 Series,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "d81d1000000000000000504944564944,iBUFFALO BSGP1204P Series,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "ff113133000000000000504944564944,SVEN X-PAD,a:b2,b:b3,y:b1,x:b0,start:b5,back:b4,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b8,righttrigger:b9,", - "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", - "__XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpdown:b1,dpleft:b2,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", -#endif - -#ifdef OSX_ENABLED - "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", - "050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,y:b9,x:b10,start:b6,guide:b8,back:b7,dpup:b2,dpleft:b0,dpdown:b3,dpright:b1,leftx:a0,lefty:a1,lefttrigger:b12,righttrigger:,leftshoulder:b11,", - "050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,x:b18,y:b17,back:b7,guide:b8,start:b6,leftstick:b23,rightstick:b24,leftshoulder:b19,rightshoulder:b20,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b21,righttrigger:b22,", - "0d0f0000000000004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "0d0f0000000000006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:a4,", - "10080000000000000100000000000000,Twin USB Joystick,a:b4,b:b2,x:b6,y:b0,back:b16,start:b18,leftstick:b20,rightstick:b22,leftshoulder:b12,rightshoulder:b14,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a2,rightx:a6,righty:a4,lefttrigger:b8,righttrigger:b10,", - "10280000000000000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "2509000000000000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", - "4c05000000000000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", - "4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "4c05000000000000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", - "4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", - "4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", - "5e04000000000000dd02000000000000,Xbox One Wired Controller,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "5e04000000000000e002000000000000,Xbox Wireless Controller,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b10,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "5e04000000000000ea02000000000000,Xbox Wireless Controller,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", - "79000000000000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,x:b0,y:b12,back:b32,start:b36,leftstick:b40,rightstick:b44,leftshoulder:b16,rightshoulder:b20,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a4,rightx:a8,righty:a12,lefttrigger:b24,righttrigger:b28,", - "79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,", - "79000000000000001100000000000000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a3,lefty:a4,", - "81170000000000007e05000000000000,Sega Saturn,x:b0,a:b2,b:b4,y:b6,start:b13,dpleft:b15,dpdown:b16,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,lefttrigger:b10,rightshoulder:b9,righttrigger:a4,righttrigger:b11,leftx:a0,lefty:a2,", - "83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", - "891600000000000000fd000000000000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", - "8f0e0000000000000300000000000000,Piranha xtreme,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", - "AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", - "ad1b00000000000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", - "b4040000000000000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,x:b3,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", - "d814000000000000cecf000000000000,MC Cthulhu,leftx:,lefty:,rightx:,righty:,lefttrigger:b6,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,righttrigger:b7,", -#endif - -#if X11_ENABLED - "0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,x:b2,y:b3,start:b7,back:b6,guide:b8,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,lefttrigger:a5,righttrigger:a4,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "030000000d0f00000d00000000010000,hori,a:b0,b:b6,y:b2,x:b1,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,start:b9,guide:b10,back:b8,leftshoulder:b3,rightshoulder:b7,leftx:b4,lefty:b5,", - "030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7", - "030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,", - "030000000d0f00004d00000011010000,HORI Gem Pad 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,y:b0,x:b3,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,", - "030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,", - "03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,x:b3,y:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,", - "03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,y:b0,x:b3,start:b8,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,", - "03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,y:b3,x:b1,start:b7,leftshoulder:,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,rightstick:,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", - "03000000280400000140000000010000,Gravis GamePad Pro USB ,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,", - "03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,x:b0,a:b2,b:b3,y:b1,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", - "03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,y:b3,x:b0,start:b9,guide:,back:,leftstick:,rightstick:,leftshoulder:,dpleft:b15,dpdown:b14,dpright:b13,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,rightshoulder:b7,dpup:b12,", - "03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,", - "030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", - "030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", - "030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,", - "030000004c050000c405000011810000,Sony DualShock 4,a:b0,b:b1,y:b2,x:b3,start:b9,guide:b10,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", - "030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", - "030000004c050000cc09000011810000,Sony DualShock 4 (CUH-ZCT2U) (USB),a:b0,b:b1,y:b2,x:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,guide:b10,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,lefttrigger:a2,rightx:a3,righty:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", - "030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", - "030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,x:b0,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,", - "030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,x:b0,y:b3,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,x:b1,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", - "030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,y:b3,x:b1,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,", - "030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,", - "030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "030000005e0400008502000000010000,Microsoft X-Box pad (Japan),x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000005e0400008e02000001000000,Microsoft X-Box 360 pad,leftstick:b9,leftx:a0,lefty:a1,dpdown:h0.1,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:h0.2,lefttrigger:a2,x:b2,dpup:h0.4,back:b6,leftshoulder:b4,y:b3,a:b0,dpright:h0.8,righttrigger:a5,b:b1,", - "030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,", - "030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000005e0400008e02000062230000,Microsoft X-Box 360 pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", - "030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "030000005e040000d102000001010000,Microsoft X-Box One pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000005e040000dd02000003020000,Microsoft X-Box One pad v2,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000005e040000e302000003020000,Microsoft X-Box One Elite pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13,", - "030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,y:b4,x:b3,start:b8,guide:b5,back:b2,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b9,righttrigger:b10,", - "030000006d04000016c2000010010000,Logitech Logitech Dual Action,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "030000006d04000018c2000010010000,Logitech Logitech RumblePad 2 USB,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,x:b0,a:b2,b:b3,y:b1,back:b10,guide:b12,start:b11,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "030000006f0e00000103000000020000,Logic3 Controller,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000006f0e00001302000000010000,Afterglow Gamepad for Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "030000006f0e00001304000000010000,Generic X-Box pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:a0,rightstick:a3,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,", - "030000006f0e00001f01000000010000,Generic X-Box pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000006f0e00002801000011010000,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b0,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:h0.2,righttrigger:b7,b:b2,", - "030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "03000000780000000600000010010000,Microntek USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftx:a0,lefty:a1,", - "03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick ,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "03000000790000001100000010010000,RetroLink Saturn Classic Controller,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", - "030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", - "030000008916000001fd000024010000,Razer Onza Classic Edition,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick ,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", - "030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick ,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", - "030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,x:b1,a:b0,b:b4,y:b5,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,y:b1,x:b0,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,", - "03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,", - "03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,", - "03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,", - "03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", - "03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,", - "03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:a2,righttrigger:a5,", - "03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", - "03000000bd12000015d0000010010000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,", - "03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,x:b13,y:b11,back:b4,start:b5,leftstick:b14,rightstick:b15,leftshoulder:b9,rightshoulder:b8,dpup:b0,dpdown:b2,dpleft:b3,dpright:b1,leftx:a1,lefty:a0,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,y:b0,x:b1,b:b3,a:b4,leftshoulder:b2,rightshoulder:b5,back:b6,start:b7,guide:b9,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftx:a0,lefty:a1,", - "03000000c9110000f055000011010000,HJC Game GAMEPAD,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b2,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:h0.2,righttrigger:b7,b:b1,", - "03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,", - "03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,leftx:a0,lefty:a1,", - "03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,y:b1,x:b0,start:b7,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,", - "03000000fd0500002a26000000010000,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b5,rightshoulder:b7,rightx:a2,start:b11,righty:a3,dpleft:h0.8,lefttrigger:b8,x:b0,dpup:h0.1,back:b10,leftstick:b2,leftshoulder:b6,y:b1,a:b3,dpright:h0.2,righttrigger:b9,b:b4,", - "03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "03000000ff1100004133000010010000,GreenAsia Inc.USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,", - "05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,y:b3,x:b2,start:b9,guide:b10,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", - "05000000102800000900000000010000,8Bitdo SFC30 GamePad,x:b4,a:b1,b:b0,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,", - "05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,", - "05000000362800000100000004010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,", - "05000000380700006652000025010000,Mad Catz C.T.R.L.R ,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,", - "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", - "050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,", - "050000004c050000c405000000010000,Sony DualShock 4 BT,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,", - "050000004c050000cc09000000810000,Sony DualShock 4 (CUH-ZCT2U) (Bluetooth),a:b0,b:b1,y:b2,x:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,guide:b10,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,lefttrigger:a2,rightx:a3,righty:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,", - "05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,", - "050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", - "050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,x:b3,y:b2,back:b8,start:b9,guide:b10,leftshoulder:b4,rightshoulder:b5,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,", - "05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,", - "05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,x:b2,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,", - "05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,y:b3,x:b2,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,", - "060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,", - "06000000adde0000efbe000002010000,Hidromancer Game Controller,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,", -#endif - -#if defined(__ANDROID__) - "Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,", - "47656e6572696320582d426f78207061,Logitech F-310,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a5,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a4,b:b1,", - "484f524920434f2e2c4c544420205041,Hori Gem Pad 3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:b15,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,", - "4d6963726f736f667420582d426f7820,Microsoft X-Box 360 pad,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,", - "4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", - "532e542e442e20496e74657261637420,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b25,rightshoulder:b27,rightx:a2,start:b31,righty:a3,dpleft:h0.8,lefttrigger:b28,x:b20,dpup:h0.1,back:b30,leftstick:b22,leftshoulder:b26,y:b21,a:b23,dpright:h0.2,righttrigger:b29,b:b24,", - "506572666f726d616e63652044657369,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:h0.2,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,", - "4f5559412047616d6520436f6e74726f,OUYA Game Controller,leftx:a1,lefty:a3,dpdown:b12,rightstick:b8,rightshoulder:b10,rightx:a6,start:b-86,righty:a7,dpleft:b13,lefttrigger:b15,x:b2,dpup:b11,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:b14,righttrigger:b16,b:b1,", -#endif - -#ifdef JAVASCRIPT_ENABLED - "Default HTML5 Gamepad, Default Mapping,leftx:a0,lefty:a1,dpdown:b13,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:b14,lefttrigger:a6,x:b2,dpup:b12,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:b15,righttrigger:a7,b:b1,", - "303435652d303238652d4d6963726f73,Wired X360 Controller,leftx:a0,lefty:a1,dpdown:a7,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:a6,lefttrigger:a2,x:b2,dpup:a7,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:a6,righttrigger:a5,b:b1,", - "303435652d303731392d58626f782033,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,", - "303534632d303236382d536f6e792050,PS3 Controller USB/Linux,leftx:a0,lefty:a1,dpdown:b6,rightstick:b2,rightshoulder:b11,rightx:a2,start:b3,righty:a3,dpleft:b7,lefttrigger:b8,x:b15,dpup:b4,back:b0,leftstick:b1,leftshoulder:b10,y:b12,a:b14,dpright:b5,righttrigger:b9,b:b13,", - "303534632d303563342d536f6e792043,PS4 Controller USB/Linux,leftx:a0,lefty:a1,dpdown:a7,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a5,dpleft:a6,lefttrigger:a3,x:b0,dpup:a7,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:a6,righttrigger:a4,b:b2,", - "303534632d303563342d576972656c65,PS4 Controller USB/Win,leftx:a0,lefty:a1,dpdown:b15,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a5,lefttrigger:a3,x:b0,dpup:b14,dpleft:b16,dpright:b17,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,righttrigger:b7,b:b2,", - "c2a94d6963726f736f66742058626f78,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,", -#endif - -#ifdef UWP_ENABLED - "__UWP_GAMEPAD__,Xbox Controller,a:b2,b:b3,x:b4,y:b5,start:b0,back:b1,leftstick:b12,rightstick:b13,leftshoulder:b10,rightshoulder:b11,dpup:b6,dpdown:b7,dpleft:b8,dpright:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", -#endif - NULL -}; - InputDefault::InputDefault() { mouse_button_mask = 0; @@ -847,9 +562,9 @@ InputDefault::InputDefault() { }; int i = 0; - while (s_ControllerMappings[i]) { + while (DefaultControllerMappings::mappings[i]) { - parse_mapping(s_ControllerMappings[i++]); + parse_mapping(DefaultControllerMappings::mappings[i++]); }; } @@ -1109,6 +824,10 @@ void InputDefault::parse_mapping(String p_mapping) { mapping.hat[i].index = 1024 + i; Vector<String> entry = p_mapping.split(","); + if (entry.size() < 2) { + return; + } + CharString uid; uid.resize(17); diff --git a/main/main.cpp b/main/main.cpp index 4d7273b4e4..a59ca3da3b 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -127,6 +127,7 @@ static bool disable_render_loop = false; static int fixed_fps = -1; static bool auto_build_solutions = false; static bool auto_quit = false; +static bool print_fps = false; static OS::ProcessID allow_focus_steal_pid = 0; @@ -175,7 +176,7 @@ static String get_full_version_string() { String hash = String(VERSION_HASH); if (hash.length() != 0) hash = "." + hash.left(7); - return String(VERSION_MKSTRING) + hash; + return String(VERSION_FULL_BUILD) + hash; } //#define DEBUG_INIT @@ -206,6 +207,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" -e, --editor Start the editor instead of running the scene.\n"); OS::get_singleton()->print(" -p, --project-manager Start the project manager, even if a project is auto-detected.\n"); #endif + OS::get_singleton()->print(" -q, --quit Quit after the first iteration.\n"); OS::get_singleton()->print(" -l, --language <locale> Use a specific locale (<locale> being a two-letter code).\n"); OS::get_singleton()->print(" --path <directory> Path to a project (<directory> must contain a 'project.godot' file).\n"); OS::get_singleton()->print(" -u, --upwards Scan folders upwards for project.godot file.\n"); @@ -254,6 +256,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --disable-render-loop Disable render loop so rendering only occurs when called explicitly from script.\n"); OS::get_singleton()->print(" --disable-crash-handler Disable crash handler when supported by the platform code.\n"); OS::get_singleton()->print(" --fixed-fps <fps> Force a fixed number of frames per second. This setting disables real-time synchronization.\n"); + OS::get_singleton()->print(" --print-fps Print the frames per second to the stdout.\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Standalone tools:\n"); @@ -263,7 +266,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --export-debug Use together with --export, enables debug mode for the template.\n"); OS::get_singleton()->print(" --doctool <path> Dump the engine API reference to the given <path> in XML format, merging if existing files are found.\n"); OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n"); - OS::get_singleton()->print(" --build-solutions Builds the scripting solutions (IE. C#).\n"); + OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects).\n"); #ifdef DEBUG_METHODS_ENABLED OS::get_singleton()->print(" --gdnative-generate-json-api Generate JSON dump of the Godot API for GDNative bindings.\n"); #endif @@ -348,6 +351,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Vector<String> breakpoints; bool use_custom_res = true; bool force_res = false; + bool found_project = false; packed_data = PackedData::get_singleton(); if (!packed_data) @@ -558,7 +562,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } else if (I->get() == "-u" || I->get() == "--upwards") { // scan folders upwards upwards = true; - } else if (I->get() == "--quit" || I->get() == "-q") { // Auto quit at the end of the first main loop iteration + } else if (I->get() == "-q" || I->get() == "--quit") { // Auto quit at the end of the first main loop iteration auto_quit = true; } else if (I->get().ends_with("project.godot")) { String path; @@ -663,6 +667,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->print("Missing fixed-fps argument, aborting.\n"); goto error; } + } else if (I->get() == "--print-fps") { + print_fps = true; } else if (I->get() == "--disable-crash-handler") { OS::get_singleton()->disable_crash_handler(); } else { @@ -687,6 +693,19 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph I = N; } + if (globals->setup(game_path, main_pack, upwards) == OK) { + found_project = true; + } else { + +#ifdef TOOLS_ENABLED + editor = false; +#else + OS::get_singleton()->print("Error: Could not load game path '%s'.\n", game_path.ascii().get_data()); + + goto error; +#endif + } + GLOBAL_DEF("memory/limits/multithreaded_server/rid_pool_prealloc", 60); GLOBAL_DEF("network/limits/debugger_stdout/max_chars_per_second", 2048); GLOBAL_DEF("network/limits/debugger_stdout/max_messages_per_frame", 10); @@ -759,26 +778,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph #endif - if (globals->setup(game_path, main_pack, upwards) != OK) { - -#ifdef TOOLS_ENABLED - editor = false; -#else - OS::get_singleton()->print("Error: Could not load game path '%s'.\n", game_path.ascii().get_data()); - - goto error; -#endif - } else if (String(GLOBAL_DEF("application/run/main_scene", "")) == "") { -#ifdef TOOLS_ENABLED - if (!editor) { -#endif - OS::get_singleton()->print("Error: Can't run project: no main scene defined.\n"); - goto error; -#ifdef TOOLS_ENABLED - } -#endif - } - GLOBAL_DEF("logging/file_logging/enable_file_logging", false); GLOBAL_DEF("logging/file_logging/log_path", "user://logs/log.txt"); GLOBAL_DEF("logging/file_logging/max_log_files", 10); @@ -800,14 +799,21 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph if (!project_manager) { // Determine if the project manager should be requested - project_manager = - main_args.size() == 0 && - !ProjectSettings::get_singleton()->has_setting("application/run/main_loop_type") && - (!ProjectSettings::get_singleton()->has_setting("application/run/main_scene") || - String(ProjectSettings::get_singleton()->get("application/run/main_scene")) == ""); + project_manager = main_args.size() == 0 && !found_project; } #endif + if (main_args.size() == 0 && String(GLOBAL_DEF("application/run/main_scene", "")) == "") { +#ifdef TOOLS_ENABLED + if (!editor && !project_manager) { +#endif + OS::get_singleton()->print("Error: Can't run project: no main scene defined.\n"); + goto error; +#ifdef TOOLS_ENABLED + } +#endif + } + if (editor || project_manager) { use_custom_res = false; input_map->load_default(); //keys for editor @@ -827,8 +833,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->set_cmdline(execpath, main_args); - //if (video_driver == "") // useless for now, so removing - // video_driver = GLOBAL_DEF("display/driver/name", Variant((const char *)OS::get_singleton()->get_video_driver_name(0))); + GLOBAL_DEF("rendering/quality/driver/driver_name", "GLES3"); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_name", PropertyInfo(Variant::STRING, "rendering/quality/driver/driver_name", PROPERTY_HINT_ENUM, "GLES3,GLES2")); + if (video_driver == "") { + video_driver = GLOBAL_GET("rendering/quality/driver/driver_name"); + } GLOBAL_DEF("display/window/size/width", 1024); GLOBAL_DEF("display/window/size/height", 600); @@ -948,7 +957,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF("physics/common/physics_fps", 60)); Engine::get_singleton()->set_target_fps(GLOBAL_DEF("debug/settings/fps/force_fps", 0)); - GLOBAL_DEF("debug/settings/stdout/print_fps", OS::get_singleton()->is_stdout_verbose()); + GLOBAL_DEF("debug/settings/stdout/print_fps", false); if (!OS::get_singleton()->_verbose_stdout) //overridden OS::get_singleton()->_verbose_stdout = GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false); @@ -1821,9 +1830,13 @@ bool Main::iteration() { if (frame > 1000000) { - if (GLOBAL_DEF("debug/settings/stdout/print_fps", OS::get_singleton()->is_stdout_verbose()) && !editor) { - print_line("FPS: " + itos(frames)); - }; + if (editor || project_manager) { + if (print_fps) { + print_line("Editor FPS: " + itos(frames)); + } + } else if (GLOBAL_GET("debug/settings/stdout/print_fps") || print_fps) { + print_line("Game FPS: " + itos(frames)); + } Engine::get_singleton()->_fps = frames; performance->set_process_time(USEC_TO_SEC(idle_process_max)); diff --git a/main/tests/test_gui.cpp b/main/tests/test_gui.cpp index b7b6c21692..305b749717 100644 --- a/main/tests/test_gui.cpp +++ b/main/tests/test_gui.cpp @@ -185,6 +185,10 @@ public: popup->add_item("Popup"); popup->add_check_item("Check Popup"); popup->set_item_checked(4, true); + popup->add_separator(); + popup->add_radio_check_item("Option A"); + popup->set_item_checked(6, true); + popup->add_radio_check_item("Option B"); OptionButton *options = memnew(OptionButton); diff --git a/methods.py b/methods.py index f4d33fb6d8..792417866e 100644 --- a/methods.py +++ b/methods.py @@ -19,637 +19,6 @@ def add_source_files(self, sources, filetype, lib_env=None, shared=False): sources.append(self.Object(f)) -def build_shader_header(target, source, env): - - for x in source: - print(x) - - name = str(x) - name = name[name.rfind("/") + 1:] - name = name[name.rfind("\\") + 1:] - name = name.replace(".", "_") - - fs = open(str(x), "r") - fd = open(str(x) + ".gen.h", "w") - fd.write("/* this file has been generated by SCons, do not edit! */\n") - fd.write("static const char *" + name + "=\n") - line = fs.readline() - while(line): - line = line.replace("\r", "") - line = line.replace("\n", "") - line = line.replace("\\", "\\\\") - line = line.replace("\"", "\\\"") - fd.write("\"" + line + "\\n\"\n") - line = fs.readline() - - fd.write(";\n") - - return 0 - - -def build_glsl_header(filename): - - fs = open(filename, "r") - line = fs.readline() - - vertex_lines = [] - fragment_lines = [] - uniforms = [] - attributes = [] - fbos = [] - conditionals = [] - texunits = [] - texunit_names = [] - ubos = [] - ubo_names = [] - - reading = "" - line_offset = 0 - vertex_offset = 0 - fragment_offset = 0 - - while(line): - - if (line.find("[vertex]") != -1): - reading = "vertex" - line = fs.readline() - line_offset += 1 - vertex_offset = line_offset - continue - - if (line.find("[fragment]") != -1): - reading = "fragment" - line = fs.readline() - line_offset += 1 - fragment_offset = line_offset - continue - - if (line.find("#ifdef ") != -1): - ifdefline = line.replace("#ifdef ", "").strip() - if (not ifdefline in conditionals): - conditionals += [ifdefline] - - if (line.find("#elif defined(") != -1): - ifdefline = line.replace("#elif defined(", "").strip() - ifdefline = ifdefline.replace(")", "").strip() - if (not ifdefline in conditionals): - conditionals += [ifdefline] - - import re - if re.search(r"^\s*uniform", line): - - if (line.lower().find("texunit:") != -1): - # texture unit - texunit = str(int(line[line.find(":") + 1:].strip())) - uline = line[:line.lower().find("//")] - uline = uline.replace("uniform", "") - uline = uline.replace(";", "") - lines = uline.split(",") - for x in lines: - - x = x.strip() - x = x[x.rfind(" ") + 1:] - if (x.find("[") != -1): - # unfiorm array - x = x[:x.find("[")] - - if (not x in texunit_names): - texunits += [(x, texunit)] - texunit_names += [x] - - elif (line.lower().find("ubo:") != -1): - # ubo - uboidx = str(int(line[line.find(":") + 1:].strip())) - uline = line[:line.lower().find("//")] - uline = uline[uline.find("uniform") + len("uniform"):] - uline = uline.replace(";", "") - uline = uline.replace("{", "").strip() - lines = uline.split(",") - for x in lines: - - x = x.strip() - x = x[x.rfind(" ") + 1:] - if (x.find("[") != -1): - # unfiorm array - x = x[:x.find("[")] - - if (not x in ubo_names): - ubos += [(x, uboidx)] - ubo_names += [x] - - else: - uline = line.replace("uniform", "") - uline = uline.replace(";", "") - lines = uline.split(",") - for x in lines: - - x = x.strip() - x = x[x.rfind(" ") + 1:] - if (x.find("[") != -1): - # unfiorm array - x = x[:x.find("[")] - - if (not x in uniforms): - uniforms += [x] - - if ((line.strip().find("in ") == 0 or line.strip().find("attribute ") == 0) and line.find("attrib:") != -1): - uline = line.replace("in ", "") - uline = uline.replace("attribute ", "") - uline = uline.replace(";", "") - uline = uline[uline.find(" "):].strip() - - if (uline.find("//") != -1): - name, bind = uline.split("//") - if (bind.find("attrib:") != -1): - name = name.strip() - bind = bind.replace("attrib:", "").strip() - attributes += [(name, bind)] - - if (line.strip().find("out ") == 0): - uline = line.replace("out", "").strip() - uline = uline.replace(";", "") - uline = uline[uline.find(" "):].strip() - - if (uline.find("//") != -1): - name, bind = uline.split("//") - if (bind.find("drawbuffer:") != -1): - name = name.strip() - bind = bind.replace("drawbuffer:", "").strip() - fbos += [(name, bind)] - - line = line.replace("\r", "") - line = line.replace("\n", "") - line = line.replace("\\", "\\\\") - line = line.replace("\"", "\\\"") - # line=line+"\\n\\" no need to anymore - - if (reading == "vertex"): - vertex_lines += [line] - if (reading == "fragment"): - fragment_lines += [line] - - line = fs.readline() - line_offset += 1 - - fs.close() - - out_file = filename + ".gen.h" - fd = open(out_file, "w") - - fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n") - - out_file_base = out_file - out_file_base = out_file_base[out_file_base.rfind("/") + 1:] - out_file_base = out_file_base[out_file_base.rfind("\\") + 1:] -# print("out file "+out_file+" base " +out_file_base) - out_file_ifdef = out_file_base.replace(".", "_").upper() - fd.write("#ifndef " + out_file_ifdef + "\n") - fd.write("#define " + out_file_ifdef + "\n") - - out_file_class = out_file_base.replace(".glsl.h", "").title().replace("_", "").replace(".", "") + "ShaderGL" - fd.write("\n\n") - fd.write("#include \"drivers/opengl/shader_gl.h\"\n\n\n") - fd.write("class " + out_file_class + " : public ShaderGL {\n\n") - fd.write("\t virtual String get_shader_name() const { return \"" + out_file_class + "\"; }\n") - fd.write("public:\n\n") - - if (len(conditionals)): - fd.write("\tenum Conditionals {\n") - for x in conditionals: - fd.write("\t\t" + x + ",\n") - fd.write("\t};\n\n") - if (len(uniforms)): - fd.write("\tenum Uniforms {\n") - for x in uniforms: - fd.write("\t\t" + x.upper() + ",\n") - fd.write("\t};\n\n") - - fd.write("\t_FORCE_INLINE_ int get_uniform(Uniforms p_uniform) const { return _get_uniform(p_uniform); }\n\n") - if (len(conditionals)): - - fd.write("\t_FORCE_INLINE_ void set_conditional(Conditionals p_conditional,bool p_enable) { _set_conditional(p_conditional,p_enable); }\n\n") - fd.write("\t#define _FU if (get_uniform(p_uniform)<0) return; ERR_FAIL_COND( get_active()!=this );\n\n ") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, bool p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value?1:0); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, double p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint16_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int16_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint32_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int32_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n") - #fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint64_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"); - #fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int64_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"); - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, unsigned long p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, long p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Color& p_color) { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(get_uniform(p_uniform),1,col); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector2& p_vec2) { _FU GLfloat vec2[2]={p_vec2.x,p_vec2.y}; glUniform2fv(get_uniform(p_uniform),1,vec2); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector3& p_vec3) { _FU GLfloat vec3[3]={p_vec3.x,p_vec3.y,p_vec3.z}; glUniform3fv(get_uniform(p_uniform),1,vec3); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Plane& p_plane) { _FU GLfloat plane[4]={p_plane.normal.x,p_plane.normal.y,p_plane.normal.z,p_plane.d}; glUniform4fv(get_uniform(p_uniform),1,plane); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b) { _FU glUniform2f(get_uniform(p_uniform),p_a,p_b); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c) { _FU glUniform3f(get_uniform(p_uniform),p_a,p_b,p_c); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d) { _FU glUniform4f(get_uniform(p_uniform),p_a,p_b,p_c,p_d); }\n\n") - - fd.write("""\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform& p_transform) { _FU - - const Transform &tr = p_transform; - - GLfloat matrix[16]={ /* build a 16x16 matrix */ - tr.basis.elements[0][0], - tr.basis.elements[1][0], - tr.basis.elements[2][0], - 0, - tr.basis.elements[0][1], - tr.basis.elements[1][1], - tr.basis.elements[2][1], - 0, - tr.basis.elements[0][2], - tr.basis.elements[1][2], - tr.basis.elements[2][2], - 0, - tr.origin.x, - tr.origin.y, - tr.origin.z, - 1 - }; - - - glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix); - - - } - - """) - - fd.write("""\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform2D& p_transform) { _FU - - const Transform2D &tr = p_transform; - - GLfloat matrix[16]={ /* build a 16x16 matrix */ - tr.elements[0][0], - tr.elements[0][1], - 0, - 0, - tr.elements[1][0], - tr.elements[1][1], - 0, - 0, - 0, - 0, - 1, - 0, - tr.elements[2][0], - tr.elements[2][1], - 0, - 1 - }; - - - glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix); - - - } - - """) - - fd.write("""\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix) { _FU - - GLfloat matrix[16]; - - for (int i=0;i<4;i++) { - for (int j=0;j<4;j++) { - - matrix[i*4+j]=p_matrix.matrix[i][j]; - } - } - - glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix); - }; """) - - fd.write("\n\n#undef _FU\n\n\n") - - fd.write("\tvirtual void init() {\n\n") - if (len(conditionals)): - - fd.write("\t\tstatic const char* _conditional_strings[]={\n") - if (len(conditionals)): - for x in conditionals: - fd.write("\t\t\t\"#define " + x + "\\n\",\n") - fd.write("\t\t};\n\n") - else: - fd.write("\t\tstatic const char **_conditional_strings=NULL;\n") - - if (len(uniforms)): - - fd.write("\t\tstatic const char* _uniform_strings[]={\n") - if (len(uniforms)): - for x in uniforms: - fd.write("\t\t\t\"" + x + "\",\n") - fd.write("\t\t};\n\n") - else: - fd.write("\t\tstatic const char **_uniform_strings=NULL;\n") - - if (len(attributes)): - - fd.write("\t\tstatic AttributePair _attribute_pairs[]={\n") - for x in attributes: - fd.write("\t\t\t{\"" + x[0] + "\"," + x[1] + "},\n") - fd.write("\t\t};\n\n") - else: - fd.write("\t\tstatic AttributePair *_attribute_pairs=NULL;\n") - - if (len(fbos)): - fd.write("\t\tstatic FBOPair _fbo_pairs[]={\n") - for x in fbos: - fd.write("\t\t\t{\"" + x[0] + "\"," + x[1] + "},\n") - fd.write("\t\t};\n\n") - else: - fd.write("\t\tstatic FBOPair *_fbo_pairs=NULL;\n") - - if (len(ubos)): - fd.write("\t\tstatic UBOPair _ubo_pairs[]={\n") - for x in ubos: - fd.write("\t\t\t{\"" + x[0] + "\"," + x[1] + "},\n") - fd.write("\t\t};\n\n") - else: - fd.write("\t\tstatic UBOPair *_ubo_pairs=NULL;\n") - - if (len(texunits)): - fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n") - for x in texunits: - fd.write("\t\t\t{\"" + x[0] + "\"," + x[1] + "},\n") - fd.write("\t\t};\n\n") - else: - fd.write("\t\tstatic TexUnitPair *_texunit_pairs=NULL;\n") - - fd.write("\t\tstatic const char* _vertex_code=\"\\\n") - for x in vertex_lines: - fd.write("\t\t\t" + x + "\n") - fd.write("\t\t\";\n\n") - - fd.write("\t\tstatic const int _vertex_code_start=" + str(vertex_offset) + ";\n") - - fd.write("\t\tstatic const char* _fragment_code=\"\\\n") - for x in fragment_lines: - fd.write("\t\t\t" + x + "\n") - fd.write("\t\t\";\n\n") - - fd.write("\t\tstatic const int _fragment_code_start=" + str(fragment_offset) + ";\n") - - fd.write("\t\tsetup(_conditional_strings," + str(len(conditionals)) + ",_uniform_strings," + str(len(uniforms)) + ",_attribute_pairs," + str(len(attributes)) + ",_fbo_pairs," + str(len(fbos)) + ",_ubo_pairs," + str(len(ubos)) + ",_texunit_pairs," + str(len(texunits)) + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n") - fd.write("\t};\n\n") - - fd.write("};\n\n") - fd.write("#endif\n\n") - fd.close() - - -def build_glsl_headers(target, source, env): - - for x in source: - - build_glsl_header(str(x)) - - return 0 - - -def build_hlsl_dx9_header(filename): - - fs = open(filename, "r") - line = fs.readline() - - vertex_lines = [] - fragment_lines = [] - uniforms = [] - fragment_uniforms = [] - attributes = [] - fbos = [] - conditionals = [] - - reading = "" - line_offset = 0 - vertex_offset = 0 - fragment_offset = 0 - - while(line): - - if (line.find("[vertex]") != -1): - reading = "vertex" - line = fs.readline() - line_offset += 1 - vertex_offset = line_offset - continue - - if (line.find("[fragment]") != -1): - reading = "fragment" - line = fs.readline() - line_offset += 1 - fragment_offset = line_offset - continue - - if (line.find("#ifdef ") != -1): - ifdefline = line.replace("#ifdef ", "").strip() - if (not ifdefline in conditionals): - conditionals += [ifdefline] - - if (line.find("#elif defined(") != -1): - ifdefline = line.replace("#elif defined(", "").strip() - ifdefline = ifdefline.replace(")", "").strip() - if (not ifdefline in conditionals): - conditionals += [ifdefline] - if (line.find("uniform") != -1): - uline = line.replace("uniform", "") - uline = uline.replace(";", "") - lines = uline.split(",") - for x in lines: - - x = x.strip() - x = x[x.rfind(" ") + 1:] - if (x.find("[") != -1): - # unfiorm array - x = x[:x.find("[")] - - if (not x in uniforms): - uniforms += [x] - fragment_uniforms += [reading == "fragment"] - line = line.replace("\r", "") - line = line.replace("\n", "") - line = line.replace("\\", "\\\\") - line = line.replace("\"", "\\\"") - line = line + "\\n\\" - - if (reading == "vertex"): - vertex_lines += [line] - if (reading == "fragment"): - fragment_lines += [line] - - line = fs.readline() - line_offset += 1 - - fs.close() - - out_file = filename + ".gen.h" - fd = open(out_file, "w") - - fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n") - - out_file_base = out_file - out_file_base = out_file_base[out_file_base.rfind("/") + 1:] - out_file_base = out_file_base[out_file_base.rfind("\\") + 1:] -# print("out file "+out_file+" base " +out_file_base) - out_file_ifdef = out_file_base.replace(".", "_").upper() - fd.write("#ifndef " + out_file_ifdef + "\n") - fd.write("#define " + out_file_ifdef + "\n") - - out_file_class = out_file_base.replace(".hlsl.h", "").title().replace("_", "").replace(".", "") + "ShaderDX9" - fd.write("\n\n") - fd.write("#include \"drivers/directx9/shader_dx9.h\"\n\n\n") - fd.write("class " + out_file_class + " : public ShaderDX9 {\n\n") - fd.write("\t virtual String get_shader_name() const { return \"" + out_file_class + "\"; }\n") - fd.write("public:\n\n") - - if (len(conditionals)): - fd.write("\tenum Conditionals {\n") - for x in conditionals: - fd.write("\t\t" + x + ",\n") - fd.write("\t};\n\n") - if (len(uniforms)): - fd.write("\tenum Uniforms {\n") - for x in uniforms: - fd.write("\t\t" + x.upper() + ",\n") - fd.write("\t};\n\n") - - if (len(conditionals)): - fd.write("\t_FORCE_INLINE_ void set_conditional(Conditionals p_conditional,bool p_enable) { _set_conditional(p_conditional,p_enable); }\n\n") - - fd.write("\t#define _FU if (!_uniform_valid(p_uniform)) return; ERR_FAIL_COND( get_active()!=this );\n\n ") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, bool p_value) { _FU set_uniformb(p_uniform,p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_value) { _FU set_uniformf(p_uniform,p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, double p_value) { _FU set_uniformf(p_uniform,p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint8_t p_value) { _FU set_uniformi(p_uniform,p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int8_t p_value) { _FU set_uniformi(p_uniform,p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint16_t p_value) { _FU set_uniformi(p_uniform,p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int16_t p_value) { _FU set_uniformi(p_uniform,p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint32_t p_value) { _FU set_uniformi(p_uniform,p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int32_t p_value) { _FU set_uniformi(p_uniform,p_value); }\n\n") - #fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint64_t p_value) { _FU set_uniformi(p_uniform,p_value); }\n\n"); - #fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int64_t p_value) { _FU set_uniformi(p_uniform,p_value); }\n\n"); - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, unsigned long p_value) { _FU set_uniformi(p_uniform,p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, long p_value) { _FU set_uniformi(p_uniform,p_value); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Color& p_color) { _FU float col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; set_uniformfv(p_uniform,col); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector2& p_vec2) { _FU float vec2[4]={p_vec2.x,p_vec2.y,0,0}; set_uniformfv(p_uniform,vec2); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector3& p_vec3) { _FU float vec3[4]={p_vec3.x,p_vec3.y,p_vec3.z,0}; set_uniformfv(p_uniform,vec3); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b) { _FU float vec2[4]={p_a,p_b,0,0}; set_uniformfv(p_uniform,vec2); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c) { _FU float vec3[4]={p_a,p_b,p_c,0}; set_uniformfv(p_uniform,vec3); }\n\n") - fd.write("\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d) { _FU float vec4[4]={p_a,p_b,p_c,p_d}; set_uniformfv(p_uniform,vec4); }\n\n") - - fd.write("""\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform& p_transform) { _FU - - const Transform &tr = p_transform; - - float matrix[16]={ /* build a 16x16 matrix */ - tr.basis.elements[0][0], - tr.basis.elements[0][1], - tr.basis.elements[0][2], - tr.origin.x, - tr.basis.elements[1][0], - tr.basis.elements[1][1], - tr.basis.elements[1][2], - tr.origin.y, - tr.basis.elements[2][0], - tr.basis.elements[2][1], - tr.basis.elements[2][2], - tr.origin.z, - 0, - 0, - 0, - 1 - }; - - set_uniformfv(p_uniform,&matrix[0],4); - - } - - """) - - fd.write("""\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix) { _FU - - float matrix[16]; - - for (int i=0;i<4;i++) { - for (int j=0;j<4;j++) { - - matrix[i*4+j]=p_matrix.matrix[j][i]; - } - } - - set_uniformfv(p_uniform,&matrix[0],4); - }; """) - - fd.write("\n\n#undef _FU\n\n\n") - - fd.write("\tvirtual void init(IDirect3DDevice9 *p_device,ShaderSupport p_version) {\n\n") - if (len(conditionals)): - - fd.write("\t\tstatic const char* _conditional_strings[]={\n") - if (len(conditionals)): - for x in conditionals: - fd.write("\t\t\t\"" + x + "\",\n") - fd.write("\t\t};\n\n") - else: - fd.write("\t\tstatic const char **_conditional_strings=NULL;\n") - - if (len(uniforms)): - - fd.write("\t\tstatic const char* _uniform_strings[]={\n") - if (len(uniforms)): - for x in uniforms: - fd.write("\t\t\t\"" + x + "\",\n") - fd.write("\t\t};\n\n") - - fd.write("\t\tstatic const bool _fragment_uniforms[]={\n") - - if (len(uniforms)): - for x in fragment_uniforms: - if (x): - fd.write("\t\t\ttrue,\n") - else: - fd.write("\t\t\tfalse,\n") - fd.write("\t\t};\n\n") - else: - fd.write("\t\tstatic const char **_uniform_strings=NULL;\n") - fd.write("\t\tstatic const bool *_fragment_uniforms=NULL;\n") - - fd.write("\t\tstatic const char* _vertex_code=\"\\\n") - for x in vertex_lines: - fd.write("\t\t\t" + x + "\n") - fd.write("\t\t\";\n\n") - - fd.write("\t\tstatic const int _vertex_code_start=" + str(vertex_offset) + ";\n") - - fd.write("\t\tstatic const char* _fragment_code=\"\\\n") - for x in fragment_lines: - fd.write("\t\t\t" + x + "\n") - fd.write("\t\t\";\n\n") - - fd.write("\t\tstatic const int _fragment_code_start=" + str(fragment_offset) + ";\n") - - fd.write("\t\tsetup(p_device,p_version,_conditional_strings," + str(len(conditionals)) + ",_uniform_strings," + str(len(uniforms)) + ",_fragment_uniforms,_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n") - fd.write("\t};\n\n") - - fd.write("};\n\n") - fd.write("#endif\n\n") - fd.close() - - -def build_hlsl_dx9_headers(target, source, env): - - for x in source: - - build_hlsl_dx9_header(str(x)) - - return 0 - class LegacyGLHeaderStruct: @@ -840,7 +209,7 @@ def include_file_in_legacygl_header(filename, header_data, depth): return header_data -def build_legacygl_header(filename, include, class_suffix, output_attribs): +def build_legacygl_header(filename, include, class_suffix, output_attribs, gles2=False): header_data = LegacyGLHeaderStruct() include_file_in_legacygl_header(filename, header_data, 0) @@ -928,14 +297,14 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): }; - glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix); + glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix); } """) - fd.write("""\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform2D& p_transform) { _FU + fd.write("""_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform2D& p_transform) { _FU const Transform2D &tr = p_transform; @@ -959,14 +328,14 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): }; - glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix); + glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix); } """) - fd.write("""\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix) { _FU + fd.write("""_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix) { _FU GLfloat matrix[16]; @@ -978,7 +347,7 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): } glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix); - }; """) + } """) fd.write("\n\n#undef _FU\n\n\n") @@ -1061,7 +430,7 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): feedback_count = 0 - if (len(header_data.feedbacks)): + if (not gles2 and len(header_data.feedbacks)): fd.write("\t\tstatic const Feedback _feedbacks[]={\n") for x in header_data.feedbacks: @@ -1076,7 +445,10 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): fd.write("\t\t};\n\n") else: - fd.write("\t\tstatic const Feedback* _feedbacks=NULL;\n") + if gles2: + pass + else: + fd.write("\t\tstatic const Feedback* _feedbacks=NULL;\n") if (len(header_data.texunits)): fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n") @@ -1086,13 +458,16 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): else: fd.write("\t\tstatic TexUnitPair *_texunit_pairs=NULL;\n") - if (len(header_data.ubos)): + if (not gles2 and len(header_data.ubos)): fd.write("\t\tstatic UBOPair _ubo_pairs[]={\n") for x in header_data.ubos: fd.write("\t\t\t{\"" + x[0] + "\"," + x[1] + "},\n") fd.write("\t\t};\n\n") else: - fd.write("\t\tstatic UBOPair *_ubo_pairs=NULL;\n") + if gles2: + pass + else: + fd.write("\t\tstatic UBOPair *_ubo_pairs=NULL;\n") fd.write("\t\tstatic const char _vertex_code[]={\n") for x in header_data.vertex_lines: @@ -1115,11 +490,17 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): fd.write("\t\tstatic const int _fragment_code_start=" + str(header_data.fragment_offset) + ";\n") if output_attribs: - fd.write("\t\tsetup(_conditional_strings," + str(len(header_data.conditionals)) + ",_uniform_strings," + str(len(header_data.uniforms)) + ",_attribute_pairs," + str(len(header_data.attributes)) + ", _texunit_pairs," + str(len(header_data.texunits)) + ",_ubo_pairs," + str(len(header_data.ubos)) + ",_feedbacks," + str(feedback_count) + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n") + if gles2: + fd.write("\t\tsetup(_conditional_strings," + str(len(header_data.conditionals)) + ",_uniform_strings," + str(len(header_data.uniforms)) + ",_attribute_pairs," + str(len(header_data.attributes)) + ", _texunit_pairs," + str(len(header_data.texunits)) + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n") + else: + fd.write("\t\tsetup(_conditional_strings," + str(len(header_data.conditionals)) + ",_uniform_strings," + str(len(header_data.uniforms)) + ",_attribute_pairs," + str(len(header_data.attributes)) + ", _texunit_pairs," + str(len(header_data.texunits)) + ",_ubo_pairs," + str(len(header_data.ubos)) + ",_feedbacks," + str(feedback_count) + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n") else: - fd.write("\t\tsetup(_conditional_strings," + str(len(header_data.conditionals)) + ",_uniform_strings," + str(len(header_data.uniforms)) + ",_texunit_pairs," + str(len(header_data.texunits)) + ",_enums," + str(len(header_data.enums)) + ",_enum_values," + str(enum_value_count) + ",_ubo_pairs," + str(len(header_data.ubos)) + ",_feedbacks," + str(feedback_count) + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n") + if gles2: + fd.write("\t\tsetup(_conditional_strings," + str(len(header_data.conditionals)) + ",_uniform_strings," + str(len(header_data.uniforms)) + ",_texunit_pairs," + str(len(header_data.texunits)) + ",_enums," + str(len(header_data.enums)) + ",_enum_values," + str(enum_value_count) + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n") + else: + fd.write("\t\tsetup(_conditional_strings," + str(len(header_data.conditionals)) + ",_uniform_strings," + str(len(header_data.uniforms)) + ",_texunit_pairs," + str(len(header_data.texunits)) + ",_enums," + str(len(header_data.enums)) + ",_enum_values," + str(enum_value_count) + ",_ubo_pairs," + str(len(header_data.ubos)) + ",_feedbacks," + str(feedback_count) + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n") - fd.write("\t};\n\n") + fd.write("\t}\n\n") if (len(enum_constants)): @@ -1134,20 +515,16 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): fd.close() -def build_legacygl_headers(target, source, env): +def build_gles3_headers(target, source, env): for x in source: - - build_legacygl_header(str(x), include="drivers/legacygl/shader_lgl.h", class_suffix="LGL", output_attribs=False) - - return 0 + build_legacygl_header(str(x), include="drivers/gles3/shader_gles3.h", class_suffix="GLES3", output_attribs=True) -def build_gles3_headers(target, source, env): +def build_gles2_headers(target, source, env): for x in source: - build_legacygl_header(str(x), include="drivers/gles3/shader_gles3.h", class_suffix="GLES3", output_attribs=True) - + build_legacygl_header(str(x), include="drivers/gles2/shader_gles2.h", class_suffix="GLES2", output_attribs=True, gles2=True) def add_module_version_string(self,s): self.module_version_string += "." + s @@ -1220,43 +597,7 @@ def parse_cg_file(fname, uniforms, sizes, conditionals): line = fs.readline() - -def build_cg_shader(sname): - - vp_uniforms = [] - vp_uniform_sizes = [] - vp_conditionals = [] - - parse_cg_file("vp_" + sname + ".cg", vp_uniforms, vp_uniform_sizes, vp_conditionals) - - fp_uniforms = [] - fp_uniform_sizes = [] - fp_conditionals = [] - - parse_cg_file("fp_" + sname + ".cg", fp_uniforms, fp_uniform_sizes, fp_conditionals) - - fd = open("shader_" + sname + ".cg.gen.h", "w") - - fd.write('\n#include "shader_cell.h"\n') - fd.write("\nclass Shader_" + sname + " : public ShaderCell {\n") - fd.write("\n\tstatic struct VertexUniforms[] = {\n") - - offset = 0 - for i in range(0, len(vp_uniforms)): - - fd.write('\t\t{ "%s", %d, %d },\n' % (vp_uniforms[i], offset, vp_uniform_sizes[i])) - offset = offset + vp_uniform_sizes[i] - fd.write("\t};\n\n") - - fd.write("public:\n\n") - - fd.write("\tenum {\n") - - for i in range(0, len(vp_uniforms)): - - fd.write('\t\tVP_%s,\n' % vp_uniforms[i].upper()) - - fd.write("\t};\n") + fs.close() import glob @@ -1306,8 +647,8 @@ void unregister_module_types() { } """ - f = open("modules/register_module_types.gen.cpp", "w") - f.write(modules_cpp) + with open("modules/register_module_types.gen.cpp", "w") as f: + f.write(modules_cpp) return module_list @@ -1406,18 +747,18 @@ def android_add_default_config(self, config): def android_add_to_manifest(self, file): base_path = self.Dir(".").abspath + "/modules/" + self.current_module + "/" + file - f = open(base_path, "r") - self.android_manifest_chunk += f.read() + with open(base_path, "r") as f: + self.android_manifest_chunk += f.read() def android_add_to_permissions(self, file): base_path = self.Dir(".").abspath + "/modules/" + self.current_module + "/" + file - f = open(base_path, "r") - self.android_permission_chunk += f.read() + with open(base_path, "r") as f: + self.android_permission_chunk += f.read() def android_add_to_attributes(self, file): base_path = self.Dir(".").abspath + "/modules/" + self.current_module + "/" + file - f = open(base_path, "r") - self.android_appattributes_chunk += f.read() + with open(base_path, "r") as f: + self.android_appattributes_chunk += f.read() def disable_module(self): self.disabled_modules.append(self.current_module) @@ -1432,7 +773,7 @@ def use_windows_spawn_fix(self, platform=None): # that makes object files with same names to be overwritten so the last wins and # the library looses symbols defined by overwritten objects. # By enabling quick append instead of the default mode (replacing), libraries will - # got built correctly regardless the invokation strategy. + # got built correctly regardless the invocation strategy. # Furthermore, since SCons will rebuild the library from scratch when an object file # changes, no multiple versions of the same object file will be present. self.Replace(ARFLAGS='q') @@ -1440,13 +781,10 @@ def use_windows_spawn_fix(self, platform=None): import subprocess def mySubProcess(cmdline, env): - prefix = "" - if(platform == 'javascript'): - prefix = "python.exe " startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW - proc = subprocess.Popen(prefix + cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, + proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=startupinfo, shell=False, env=env) data, err = proc.communicate() rv = proc.wait() @@ -1548,9 +886,11 @@ def save_active_platforms(apnames, ap): str += "};\n" + pngf.close() + wf = x + "/" + name + ".gen.h" - pngw = open(wf, "w") - pngw.write(str) + with open(wf, "w") as pngw: + pngw.write(str) def no_verbose(sys, env): @@ -1607,7 +947,7 @@ def detect_visual_c_compiler_version(tools_env): # There is no flag to give to visual c compilers to set the architecture, ie scons bits argument (32,64,ARM etc) # There are many different cl.exe files that are run, and each one compiles & links to a different architecture # As far as I know, the only way to figure out what compiler will be run when Scons calls cl.exe via Program() - # is to check the PATH variable and figure out which one will be called first. Code bellow does that and returns: + # is to check the PATH variable and figure out which one will be called first. Code below does that and returns: # the following string values: # "" Compiler not detected @@ -1627,7 +967,7 @@ def detect_visual_c_compiler_version(tools_env): if 'VCINSTALLDIR' in tools_env: # print("Checking VCINSTALLDIR") - # find() works with -1 so big ifs bellow are needed... the simplest solution, in fact + # find() works with -1 so big ifs below are needed... the simplest solution, in fact # First test if amd64 and amd64_x86 compilers are present in the path vc_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN\\amd64;") if(vc_amd64_compiler_detection_index > -1): @@ -1710,8 +1050,8 @@ def generate_cpp_hint_file(filename): pass else: try: - fd = open(filename, "w") - fd.write("#define GDCLASS(m_class, m_inherits)\n") + with open(filename, "w") as fd: + fd.write("#define GDCLASS(m_class, m_inherits)\n") except IOError: print("Could not write cpp.hint file.") diff --git a/misc/dist/html/default.html b/misc/dist/html/default.html index a1a4e89d02..4e3515a7b6 100644 --- a/misc/dist/html/default.html +++ b/misc/dist/html/default.html @@ -244,9 +244,6 @@ $GODOT_HEAD_INCLUDE var statusMode = 'hidden'; var indeterminiateStatusAnimationId = 0; - setStatusMode('indeterminate'); - engine.setCanvas(canvas); - function setStatusMode(mode) { if (statusMode === mode || !initializing) @@ -367,18 +364,27 @@ $GODOT_HEAD_INCLUDE }); } - engine.startGame(BASENAME + '.pck').then(() => { - setStatusMode('hidden'); - initializing = false; - }, err => { + function displayFailureNotice(err) { + var msg = err.message || err; if (DEBUG_ENABLED) { - printError(err.message); - console.warn(err); + printError(msg); } - setStatusNotice(err.message); + console.error(msg); + setStatusNotice(msg); setStatusMode('notice'); initializing = false; - }); + }; + + if (!Engine.isWebGLAvailable()) { + displayFailureNotice("WebGL not available"); + } else { + setStatusMode('indeterminate'); + engine.setCanvas(canvas); + engine.startGame(BASENAME + '.pck').then(() => { + setStatusMode('hidden'); + initializing = false; + }, displayFailureNotice); + } })(); //]]></script> </body> diff --git a/misc/dist/linux/godot.6 b/misc/dist/linux/godot.6 index 22836e03ed..26ebe01af7 100644 --- a/misc/dist/linux/godot.6 +++ b/misc/dist/linux/godot.6 @@ -1,4 +1,4 @@ -.TH GODOT "6" "January 2018" "godot 3.0" "Games" +.TH GODOT "6" "February 2018" "godot 3.1" "Games" .SH NAME godot \- multi\-platform 2D and 3D game engine with a feature\-rich editor .SH SYNOPSIS @@ -31,6 +31,9 @@ Start the editor instead of running the scene. \fB\-p\fR, \fB\-\-project\-manager\fR Start the project manager, even if a project is auto\-detected. .TP +\fB\-q\fR, \fB\-\-quit\fR +Quit after the first iteration. +.TP \fB\-l\fR, \fB\-\-language\fR <locale> Use a specific locale (<locale> being a two\-letter code). .TP @@ -56,7 +59,7 @@ Password for remote filesystem. Audio driver ('PulseAudio', 'ALSA'). .TP \fB\-\-video\-driver\fR <driver> -Video driver ('GLES3'). +Video driver ('GLES3', 'GLES2'). .SS "Display options:" .TP \fB\-f\fR, \fB\-\-fullscreen\fR @@ -68,6 +71,9 @@ Request a maximized window. \fB\-w\fR, \fB\-\-windowed\fR Request windowed mode. .TP +\fB\-t\fR, \fB\-\-always\-on\-top\fR +Request an always\-on\-top window. +.TP \fB\-\-resolution\fR <W>x<H> Request window resolution. .TP @@ -113,6 +119,9 @@ Disable crash handler when supported by the platform code. .TP \fB\-\-fixed\-fps\fR <fps> Force a fixed number of frames per second. This setting disables real\-time synchronization. +.TP +\fB\-\-print\-fps\fR +Print the frames per second to the stdout. .SS "Standalone tools:" .TP \fB\-s\fR, \fB\-\-script\fR <script> @@ -130,6 +139,9 @@ Dump the engine API reference to the given <path> in XML format, merging if exis \fB\-\-no\-docbase\fR Disallow dumping the base types (used with \fB\-\-doctool\fR). .TP +\fB\-\-build\-solutions\fR +Build the scripting solutions (e.g. for C# projects). +.TP \fB\-\-gdnative\-generate\-json\-api\fR Generate JSON dump of the Godot API for GDNative bindings. .TP diff --git a/misc/dist/linux/godot.appdata.xml b/misc/dist/linux/godot.appdata.xml index 907fe1f3be..a381556025 100644 --- a/misc/dist/linux/godot.appdata.xml +++ b/misc/dist/linux/godot.appdata.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright 2017 Rémi Verschelde <akien@godotengine.org> --> +<!-- Copyright 2017-2018 Rémi Verschelde <akien@godotengine.org> --> <component type="desktop"> <id>godot.desktop</id> <metadata_license>CC0-1.0</metadata_license> diff --git a/misc/dist/linux/godot.desktop b/misc/dist/linux/godot.desktop index 545c491256..974352b117 100644 --- a/misc/dist/linux/godot.desktop +++ b/misc/dist/linux/godot.desktop @@ -2,7 +2,7 @@ Name=Godot Engine GenericName=Libre game engine Comment=Multi-platform 2D and 3D game engine with a feature rich editor -Exec=godot -pm +Exec=godot -p Icon=godot Terminal=false Type=Application diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format index 8ef4e27748..016a43038b 100755 --- a/misc/hooks/pre-commit-clang-format +++ b/misc/hooks/pre-commit-clang-format @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # git pre-commit hook that runs a clang-format stylecheck. # Features: diff --git a/misc/scripts/fix_headers.py b/misc/scripts/fix_headers.py index 809820c20f..48b9628b1f 100644 --- a/misc/scripts/fix_headers.py +++ b/misc/scripts/fix_headers.py @@ -92,9 +92,11 @@ while (fname != ""): fileread.close() # Write - fileread = open(fname.strip(), "wb") - fileread.write(text) - fileread.close() + filewrite = open(fname.strip(), "wb") + filewrite.write(text) + filewrite.close() # Next file fname = files.readline() + +files.close()
\ No newline at end of file diff --git a/misc/scripts/make_glwrapper.py b/misc/scripts/make_glwrapper.py index 5694d2327e..15b66a950b 100644 --- a/misc/scripts/make_glwrapper.py +++ b/misc/scripts/make_glwrapper.py @@ -16,9 +16,7 @@ READ_CONSTANTS = 2 read_what = READ_TYPES -for x in (range(len(sys.argv) - 1)): - f = open(sys.argv[x + 1], "r") - +def read_file(f): while(True): line = f.readline() @@ -86,6 +84,9 @@ for x in (range(len(sys.argv) - 1)): functions.append(funcdata) print(funcdata) +for path in sys.argv[1:]: + with open(path, "r") as f: + read_file(f) # print(types) # print(constants) @@ -156,6 +157,7 @@ f.write("void glWrapperInit( GLWrapperFuncPtr (*wrapperFunc)(const char*) );\n") f.write("#ifdef __cplusplus\n}\n#endif\n") f.write("#endif\n\n") +f.close() f = open("glwrapper.c", "w") @@ -176,3 +178,4 @@ for x in functions: f.write("\n\n") f.write("}\n") f.write("\n\n") +f.close() diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index 648919e612..ec78cddb6a 100644 --- a/modules/bullet/area_bullet.cpp +++ b/modules/bullet/area_bullet.cpp @@ -68,7 +68,8 @@ AreaBullet::AreaBullet() : } AreaBullet::~AreaBullet() { - remove_all_overlapping_instantly(); + // Call "remove_all_overlapping_instantly();" is not necessary because the exit + // signal are handled by godot, so just clear the array } void AreaBullet::dispatch_callbacks() { @@ -131,12 +132,13 @@ void AreaBullet::remove_all_overlapping_instantly() { overlappingObjects.clear(); } -void AreaBullet::remove_overlapping_instantly(CollisionObjectBullet *p_object) { +void AreaBullet::remove_overlapping_instantly(CollisionObjectBullet *p_object, bool p_notify) { CollisionObjectBullet *supportObject; for (int i = overlappingObjects.size() - 1; 0 <= i; --i) { supportObject = overlappingObjects[i].object; if (supportObject == p_object) { - call_event(supportObject, PhysicsServer::AREA_BODY_REMOVED); + if (p_notify) + call_event(supportObject, PhysicsServer::AREA_BODY_REMOVED); supportObject->on_exit_area(this); overlappingObjects.remove(i); break; diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index 78136d574b..4104780de9 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -152,7 +152,7 @@ public: void remove_all_overlapping_instantly(); // Dispatch the callbacks and removes from overlapping list - void remove_overlapping_instantly(CollisionObjectBullet *p_object); + void remove_overlapping_instantly(CollisionObjectBullet *p_object, bool p_notify); virtual void on_collision_filters_change(); virtual void on_collision_checker_start() {} diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index 595e4951a2..6246a295ec 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -89,7 +89,9 @@ BulletPhysicsServer::BulletPhysicsServer() : active(true), active_spaces_count(0) {} -BulletPhysicsServer::~BulletPhysicsServer() {} +BulletPhysicsServer::~BulletPhysicsServer() { + bulletdelete(emptyShape); +} RID BulletPhysicsServer::shape_create(ShapeType p_shape) { ShapeBullet *shape = NULL; @@ -619,11 +621,11 @@ uint32_t BulletPhysicsServer::body_get_collision_mask(RID p_body) const { } void BulletPhysicsServer::body_set_user_flags(RID p_body, uint32_t p_flags) { - WARN_PRINT("This function si not currently supported by bullet and Godot"); + // This function si not currently supported } uint32_t BulletPhysicsServer::body_get_user_flags(RID p_body) const { - WARN_PRINT("This function si not currently supported by bullet and Godot"); + // This function si not currently supported return 0; } @@ -783,22 +785,27 @@ int BulletPhysicsServer::body_get_max_contacts_reported(RID p_body) const { return body->get_max_collisions_detection(); } -void BulletPhysicsServer::body_set_contacts_reported_depth_threshold(RID p_body, float p_treshold) { - WARN_PRINT("Not supported by bullet and even Godot"); +void BulletPhysicsServer::body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) { + // Not supported by bullet and even Godot } float BulletPhysicsServer::body_get_contacts_reported_depth_threshold(RID p_body) const { - WARN_PRINT("Not supported by bullet and even Godot"); + // Not supported by bullet and even Godot return 0.; } void BulletPhysicsServer::body_set_omit_force_integration(RID p_body, bool p_omit) { - WARN_PRINT("Not supported by bullet"); + RigidBodyBullet *body = rigid_body_owner.get(p_body); + ERR_FAIL_COND(!body); + + body->set_omit_forces_integration(p_omit); } bool BulletPhysicsServer::body_is_omitting_force_integration(RID p_body) const { - WARN_PRINT("Not supported by bullet"); - return false; + RigidBodyBullet *body = rigid_body_owner.get(p_body); + ERR_FAIL_COND_V(!body, false); + + return body->get_omit_forces_integration(); } void BulletPhysicsServer::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) { @@ -979,11 +986,11 @@ PhysicsServer::JointType BulletPhysicsServer::joint_get_type(RID p_joint) const } void BulletPhysicsServer::joint_set_solver_priority(RID p_joint, int p_priority) { - //WARN_PRINTS("Joint priority not supported by bullet"); + // Joint priority not supported by bullet } int BulletPhysicsServer::joint_get_solver_priority(RID p_joint) const { - //WARN_PRINTS("Joint priority not supported by bullet"); + // Joint priority not supported by bullet return 0; } diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 885d58d98d..e931915bba 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -239,7 +239,7 @@ public: virtual void body_set_max_contacts_reported(RID p_body, int p_contacts); virtual int body_get_max_contacts_reported(RID p_body) const; - virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_treshold); + virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold); virtual float body_get_contacts_reported_depth_threshold(RID p_body) const; virtual void body_set_omit_force_integration(RID p_body, bool p_omit); diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index 34aff68a4a..77f8df34cb 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -68,12 +68,10 @@ CollisionObjectBullet::CollisionObjectBullet(Type p_type) : force_shape_reset(false) {} CollisionObjectBullet::~CollisionObjectBullet() { - // Remove all overlapping + // Remove all overlapping, notify is not required since godot take care of it for (int i = areasOverlapped.size() - 1; 0 <= i; --i) { - areasOverlapped[i]->remove_overlapping_instantly(this); + areasOverlapped[i]->remove_overlapping_instantly(this, /*Notify*/ false); } - // not required - // areasOverlapped.clear(); destroyBulletCollisionObject(); } diff --git a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml b/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml index 8c8647e097..a4dc61d0bc 100644 --- a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml +++ b/modules/bullet/doc_classes/BulletPhysicsDirectBodyState.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BulletPhysicsDirectBodyState" inherits="PhysicsDirectBodyState" category="Core" version="3.1-dev"> +<class name="BulletPhysicsDirectBodyState" inherits="PhysicsDirectBodyState" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/bullet/doc_classes/BulletPhysicsServer.xml b/modules/bullet/doc_classes/BulletPhysicsServer.xml index 8ed84e1dec..1486936cf4 100644 --- a/modules/bullet/doc_classes/BulletPhysicsServer.xml +++ b/modules/bullet/doc_classes/BulletPhysicsServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BulletPhysicsServer" inherits="PhysicsServer" category="Core" version="3.1-dev"> +<class name="BulletPhysicsServer" inherits="PhysicsServer" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h index fe5d8418b7..fa58e86589 100644 --- a/modules/bullet/godot_motion_state.h +++ b/modules/bullet/godot_motion_state.h @@ -87,7 +87,7 @@ public: public: /// Use this function to move kinematic body - /// -- or set initial transfom before body creation. + /// -- or set initial transform before body creation. void moveBody(const btTransform &newWorldTransform) { bodyKinematicWorldTransf = newWorldTransform; } diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp index 7c051f8f17..caa3d677dd 100644 --- a/modules/bullet/godot_result_callbacks.cpp +++ b/modules/bullet/godot_result_callbacks.cpp @@ -63,6 +63,9 @@ bool GodotClosestRayResultCallback::needsCollision(btBroadphaseProxy *proxy0) co } bool GodotAllConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { + if (count >= m_resultMax) + return false; + const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask); if (needs) { btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject); @@ -70,6 +73,7 @@ bool GodotAllConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) con if (m_exclude->has(gObj->get_self())) { return false; } + return true; } else { return false; @@ -87,7 +91,7 @@ btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalCo result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id); ++count; - return count < m_resultMax; + return 1; // not used by bullet } bool GodotKinClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { @@ -181,6 +185,9 @@ btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, con } bool GodotContactPairContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { + if (m_count >= m_resultMax) + return false; + const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask); if (needs) { btCollisionObject *btObj = static_cast<btCollisionObject *>(proxy0->m_clientObject); @@ -206,7 +213,7 @@ btScalar GodotContactPairContactResultCallback::addSingleResult(btManifoldPoint ++m_count; - return m_count < m_resultMax; + return 1; // Not used by bullet } bool GodotRestInfoContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const { @@ -252,23 +259,17 @@ btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp m_collided = true; } - return cp.getDistance(); + return 1; // Not used by bullet } void GodotDeepPenetrationContactResultCallback::addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth) { - if (depth < 0) { - // Has penetration - if (m_most_penetrated_distance > depth) { + if (m_penetration_distance > depth) { // Has penetration? - bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); - - m_most_penetrated_distance = depth; - m_pointCollisionObject = (isSwapped ? m_body0Wrap : m_body1Wrap)->getCollisionObject(); - m_other_compound_shape_index = isSwapped ? m_index1 : m_index0; - m_pointNormalWorld = isSwapped ? normalOnBInWorld * -1 : normalOnBInWorld; - m_pointWorld = isSwapped ? (pointInWorldOnB + normalOnBInWorld * depth) : pointInWorldOnB; - m_penetration_distance = depth; - } + bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); + m_penetration_distance = depth; + m_other_compound_shape_index = isSwapped ? m_index0 : m_index1; + m_pointNormalWorld = isSwapped ? normalOnBInWorld * -1 : normalOnBInWorld; + m_pointWorld = isSwapped ? (pointInWorldOnB + (normalOnBInWorld * depth)) : pointInWorldOnB; } } diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h index ed6d4b7d6d..363051f24c 100644 --- a/modules/bullet/godot_result_callbacks.h +++ b/modules/bullet/godot_result_callbacks.h @@ -185,24 +185,18 @@ struct GodotDeepPenetrationContactResultCallback : public btManifoldResult { btVector3 m_pointWorld; btScalar m_penetration_distance; int m_other_compound_shape_index; - const btCollisionObject *m_pointCollisionObject; - - btScalar m_most_penetrated_distance; GodotDeepPenetrationContactResultCallback(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap) : btManifoldResult(body0Wrap, body1Wrap), - m_pointCollisionObject(NULL), m_penetration_distance(0), - m_other_compound_shape_index(0), - m_most_penetrated_distance(1e20) {} + m_other_compound_shape_index(0) {} void reset() { - m_pointCollisionObject = NULL; - m_most_penetrated_distance = 1e20; + m_penetration_distance = 0; } bool hasHit() { - return m_pointCollisionObject; + return m_penetration_distance < 0; } virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth); diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 75b4cc054a..2494063c22 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -255,6 +255,7 @@ RigidBodyBullet::RigidBodyBullet() : linearDamp(0), angularDamp(0), can_sleep(true), + omit_forces_integration(false), force_integration_callback(NULL), isTransformChanged(false), previousActiveState(true), @@ -334,6 +335,9 @@ void RigidBodyBullet::dispatch_callbacks() { /// The check isTransformChanged is necessary in order to call integrated forces only when the first transform is sent if ((btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && isTransformChanged) { + if (omit_forces_integration) + btBody->clearForces(); + BulletPhysicsDirectBodyState *bodyDirect = BulletPhysicsDirectBodyState::get_singleton(this); Variant variantBodyDirect = bodyDirect; @@ -437,6 +441,10 @@ bool RigidBodyBullet::is_active() const { return btBody->isActive(); } +void RigidBodyBullet::set_omit_forces_integration(bool p_omit) { + omit_forces_integration = p_omit; +} + void RigidBodyBullet::set_param(PhysicsServer::BodyParameter p_param, real_t p_value) { switch (p_param) { case PhysicsServer::BODY_PARAM_BOUNCE: diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index 2d529f6dc7..b9511243c7 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -198,6 +198,7 @@ private: real_t linearDamp; real_t angularDamp; bool can_sleep; + bool omit_forces_integration; Vector<CollisionData> collisions; // these parameters are used to avoid vector resize @@ -254,6 +255,9 @@ public: void set_activation_state(bool p_active); bool is_active() const; + void set_omit_forces_integration(bool p_omit); + _FORCE_INLINE_ bool get_omit_forces_integration() const { return omit_forces_integration; } + void set_param(PhysicsServer::BodyParameter p_param, real_t); real_t get_param(PhysicsServer::BodyParameter p_param) const; diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index 5d8d391bd9..76d9614465 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -125,14 +125,13 @@ btScaledBvhTriangleMeshShape *ShapeBullet::create_shape_concave(btBvhTriangleMes } } -btHeightfieldTerrainShape *ShapeBullet::create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size) { +btHeightfieldTerrainShape *ShapeBullet::create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) { const btScalar ignoredHeightScale(1); - const btScalar fieldHeight(500); // Meters const int YAxis = 1; // 0=X, 1=Y, 2=Z const bool flipQuadEdges = false; const void *heightsPtr = p_heights.read().ptr(); - return bulletnew(btHeightfieldTerrainShape(p_width, p_depth, heightsPtr, ignoredHeightScale, -fieldHeight, fieldHeight, YAxis, PHY_FLOAT, flipQuadEdges)); + return bulletnew(btHeightfieldTerrainShape(p_width, p_depth, heightsPtr, ignoredHeightScale, p_min_height, p_max_height, YAxis, PHY_FLOAT, flipQuadEdges)); } btRayShape *ShapeBullet::create_shape_ray(real_t p_length, bool p_slips_on_slope) { @@ -337,10 +336,10 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) { int src_face_count = faces.size(); if (0 < src_face_count) { - btTriangleMesh *shapeInterface = bulletnew(btTriangleMesh); - // It counts the faces and assert the array contains the correct number of vertices. ERR_FAIL_COND(src_face_count % 3); + + btTriangleMesh *shapeInterface = bulletnew(btTriangleMesh); src_face_count /= 3; PoolVector<Vector3>::Read r = p_faces.read(); const Vector3 *facesr = r.ptr(); @@ -387,19 +386,44 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) { Dictionary d = p_data; ERR_FAIL_COND(!d.has("width")); ERR_FAIL_COND(!d.has("depth")); - ERR_FAIL_COND(!d.has("cell_size")); ERR_FAIL_COND(!d.has("heights")); + real_t l_min_height = 0.0; + real_t l_max_height = 0.0; + + // If specified, min and max height will be used as precomputed values + if (d.has("min_height")) + l_min_height = d["min_height"]; + if (d.has("max_height")) + l_max_height = d["max_height"]; + + ERR_FAIL_COND(l_min_height > l_max_height); + int l_width = d["width"]; int l_depth = d["depth"]; - real_t l_cell_size = d["cell_size"]; PoolVector<real_t> l_heights = d["heights"]; ERR_FAIL_COND(l_width <= 0); ERR_FAIL_COND(l_depth <= 0); - ERR_FAIL_COND(l_cell_size <= CMP_EPSILON); - ERR_FAIL_COND(l_heights.size() != (width * depth)); - setup(heights, width, depth, cell_size); + ERR_FAIL_COND(l_heights.size() != (l_width * l_depth)); + + // Compute min and max heights if not specified. + if (!d.has("min_height") && !d.has("max_height")) { + + PoolVector<real_t>::Read r = heights.read(); + int heights_size = heights.size(); + + for (int i = 0; i < heights_size; ++i) { + real_t h = r[i]; + + if (h < l_min_height) + l_min_height = h; + else if (h > l_max_height) + l_max_height = h; + } + } + + setup(l_heights, l_width, l_depth, l_min_height, l_max_height); } Variant HeightMapShapeBullet::get_data() const { @@ -410,8 +434,14 @@ PhysicsServer::ShapeType HeightMapShapeBullet::get_type() const { return PhysicsServer::SHAPE_HEIGHTMAP; } -void HeightMapShapeBullet::setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size) { +void HeightMapShapeBullet::setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) { + // TODO cell size must be tweaked using localScaling, which is a shared property for all Bullet shapes + { // Copy + + // TODO If Godot supported 16-bit integer image format, we could share the same memory block for heightfields + // without having to copy anything, optimizing memory and loading performance (Bullet only reads and doesn't take ownership of the data). + const int heights_size = p_heights.size(); heights.resize(heights_size); PoolVector<real_t>::Read p_heights_r = p_heights.read(); @@ -420,14 +450,16 @@ void HeightMapShapeBullet::setup(PoolVector<real_t> &p_heights, int p_width, int heights_w[i] = p_heights_r[i]; } } + width = p_width; depth = p_depth; - cell_size = p_cell_size; + min_height = p_min_height; + max_height = p_max_height; notifyShapeChanged(); } btCollisionShape *HeightMapShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) { - btCollisionShape *cs(ShapeBullet::create_shape_height_field(heights, width, depth, cell_size)); + btCollisionShape *cs(ShapeBullet::create_shape_height_field(heights, width, depth, min_height, max_height)); cs->setLocalScaling(p_implicit_scale); prepare(cs); cs->setMargin(p_margin); diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h index 2acba90e36..abeea0f9ce 100644 --- a/modules/bullet/shape_bullet.h +++ b/modules/bullet/shape_bullet.h @@ -85,7 +85,7 @@ public: /// IMPORTANT: Remember to delete the shape interface by calling: delete my_shape->getMeshInterface(); static class btConvexPointCloudShape *create_shape_convex(btAlignedObjectArray<btVector3> &p_vertices, const btVector3 &p_local_scaling = btVector3(1, 1, 1)); static class btScaledBvhTriangleMeshShape *create_shape_concave(btBvhTriangleMeshShape *p_mesh_shape, const btVector3 &p_local_scaling = btVector3(1, 1, 1)); - static class btHeightfieldTerrainShape *create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size); + static class btHeightfieldTerrainShape *create_shape_height_field(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height); static class btRayShape *create_shape_ray(real_t p_length, bool p_slips_on_slope); }; @@ -199,7 +199,8 @@ public: PoolVector<real_t> heights; int width; int depth; - real_t cell_size; + real_t min_height; + real_t max_height; HeightMapShapeBullet(); @@ -209,7 +210,7 @@ public: virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin = 0); private: - void setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_cell_size); + void setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height); }; class RayShapeBullet : public ShapeBullet { diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 56441f7ef2..51a76ff8c5 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -628,7 +628,7 @@ void SpaceBullet::destroy_world() { void SpaceBullet::check_ghost_overlaps() { - /// Algorith support variables + /// Algorithm support variables btConvexShape *other_body_shape; btConvexShape *area_shape; btGjkPairDetector::ClosestPointInput gjk_input; @@ -660,7 +660,10 @@ void SpaceBullet::check_ghost_overlaps() { // For each overlapping for (i = ghostOverlaps.size() - 1; 0 <= i; --i) { - if (!(ghostOverlaps[i]->getUserIndex() == CollisionObjectBullet::TYPE_RIGID_BODY || ghostOverlaps[i]->getUserIndex() == CollisionObjectBullet::TYPE_AREA)) + if (ghostOverlaps[i]->getUserIndex() == CollisionObjectBullet::TYPE_AREA) { + if (!static_cast<AreaBullet *>(ghostOverlaps[i]->getUserPointer())->is_monitorable()) + continue; + } else if (ghostOverlaps[i]->getUserIndex() != CollisionObjectBullet::TYPE_RIGID_BODY) continue; otherObject = static_cast<RigidCollisionObjectBullet *>(ghostOverlaps[i]->getUserPointer()); @@ -790,7 +793,7 @@ void SpaceBullet::update_gravity() { /// I'm leaving this here just for future tests. /// Debug motion and normal vector drawing #define debug_test_motion 0 -#define PERFORM_INITIAL_UNSTACK 0 + #define RECOVERING_MOVEMENT_SCALE 0.4 #define RECOVERING_MOVEMENT_CYCLES 4 @@ -842,7 +845,6 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f G_TO_B(p_from, body_safe_position); UNSCALE_BT_BASIS(body_safe_position); -#if PERFORM_INITIAL_UNSTACK btVector3 recover_initial_position(0, 0, 0); { /// Phase one - multi shapes depenetration using margin for (int t(RECOVERING_MOVEMENT_CYCLES); 0 < t; --t) { @@ -854,7 +856,6 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f // Add recover movement in order to make it safe body_safe_position.getOrigin() += recover_initial_position; } -#endif btVector3 motion; G_TO_B(p_motion, motion); @@ -893,7 +894,7 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f btResult.m_collisionFilterGroup = p_body->get_collision_layer(); btResult.m_collisionFilterMask = p_body->get_collision_mask(); - dynamicsWorld->convexSweepTest(convex_shape_test, shape_world_from, shape_world_to, btResult, 0.002); + dynamicsWorld->convexSweepTest(convex_shape_test, shape_world_from, shape_world_to, btResult, dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration); if (btResult.hasHit()) { /// Since for each sweep test I fix the motion of new shapes in base the recover result, @@ -918,11 +919,8 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f l_has_penetration = recover_from_penetration(p_body, body_safe_position, RECOVERING_MOVEMENT_SCALE, p_infinite_inertia, delta_recover_movement, &r_recover_result); if (r_result) { -#if PERFORM_INITIAL_UNSTACK B_TO_G(motion + delta_recover_movement + recover_initial_position, r_result->motion); -#else - B_TO_G(motion + delta_recover_movement, r_result->motion); -#endif + if (l_has_penetration) { has_penetration = true; if (l_penetration_distance <= r_recover_result.penetration_distance) { @@ -1112,7 +1110,7 @@ bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btC btCollisionObjectWrapper obA(NULL, p_shapeA, p_objectA, tA, -1, p_shapeId_A); btCollisionObjectWrapper obB(NULL, p_shapeB, p_objectB, p_transformB, -1, p_shapeId_B); - btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, NULL, BT_CLOSEST_POINT_ALGORITHMS); + btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, NULL, BT_CONTACT_POINT_ALGORITHMS); if (algorithm) { GodotDeepPenetrationContactResultCallback contactPointResult(&obA, &obB); //discrete collision detection query diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml index 55a7a1ac77..7bee63019b 100644 --- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml +++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml @@ -1,12 +1,14 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NetworkedMultiplayerENet" inherits="NetworkedMultiplayerPeer" category="Core" version="3.1-dev"> +<class name="NetworkedMultiplayerENet" inherits="NetworkedMultiplayerPeer" category="Core" version="3.1"> <brief_description> PacketPeer implementation using the ENet library. </brief_description> <description> - A connection (or a listening server) that should be passed to [method SceneTree.set_network_peer]. Socket events can be handled by connecting to [SceneTree] signals. + A PacketPeer implementation that should be passed to [method SceneTree.set_network_peer] after being initialized as either a client or server. Events can then be handled by connecting to [SceneTree] signals. </description> <tutorials> + http://docs.godotengine.org/en/3.0/tutorials/networking/high_level_multiplayer.html + http://enet.bespin.org/usergroup0.html </tutorials> <demos> </demos> @@ -15,6 +17,7 @@ <return type="void"> </return> <description> + Closes the connection. Ignored if no connection is currently established. If this is a server it tries to notify all clients before forcibly disconnecting them. If this is a client it simply closes the connection to the server. </description> </method> <method name="create_client"> @@ -29,7 +32,7 @@ <argument index="3" name="out_bandwidth" type="int" default="0"> </argument> <description> - Create client that connects to a server at address [code]ip[/code] using specified [code]port[/code]. + Create client that connects to a server at address [code]ip[/code] using specified [code]port[/code]. The given IP needs to be in IPv4 or IPv6 address format, for example: [code]192.168.1.1[/code]. The [code]port[/code] is the port the server is listening on. The [code]in_bandwidth[/code] and [code]out_bandwidth[/code] parameters can be used to limit the incoming and outgoing bandwidth to the given number of bytes per second. The default of 0 means unlimited bandwidth. Note that ENet will strategically drop packets on specific sides of a connection between peers to ensure the peer's bandwidth is not overwhelmed. The bandwidth parameters also determine the window size of a connection which limits the amount of reliable packets that may be in transit at any given time. Returns [code]OK[/code] if a client was created, [code]ERR_ALREADY_IN_USE[/code] if this NetworkedMultiplayerEnet instance already has an open connection (in which case you need to call [method close_connection] first) or [code]ERR_CANT_CREATE[/code] if the client could not be created. </description> </method> <method name="create_server"> @@ -44,7 +47,7 @@ <argument index="3" name="out_bandwidth" type="int" default="0"> </argument> <description> - Create server that listens to connections via [code]port[/code]. + Create server that listens to connections via [code]port[/code]. The port needs to be an available, unused port between 0 and 65535. Note that ports below 1024 are privileged and may require elevated permissions depending on the platform. To change the interface the server listens on, use [method set_bind_ip]. The default IP is the wildcard [code]*[/code], which listens on all available interfaces. [code]max_clients[/code] is the maximum number of clients that are allowed at once, any number up to 4096 may be used, although the achievable number of simultaneous clients may be far lower and depends on the application. For additional details on the bandwidth parameters, see [method create_client]. Returns [code]OK[/code] if a server was created, [code]ERR_ALREADY_IN_USE[/code] if this NetworkedMultiplayerEnet instance already has an open connection (in which case you need to call [method close_connection] first) or [code]ERR_CANT_CREATE[/code] if the server could not be created. </description> </method> <method name="set_bind_ip"> @@ -53,23 +56,30 @@ <argument index="0" name="ip" type="String"> </argument> <description> + The IP used when creating a server. This is set to the wildcard [code]*[/code] by default, which binds to all available interfaces. The given IP needs to be in IPv4 or IPv6 address format, for example: [code]192.168.1.1[/code]. </description> </method> </methods> <members> <member name="compression_mode" type="int" setter="set_compression_mode" getter="get_compression_mode" enum="NetworkedMultiplayerENet.CompressionMode"> + The compression method used for network packets. Default is no compression. These have different tradeoffs of compression speed versus bandwidth, you may need to test which one works best for your use case if you use compression at all. </member> </members> <constants> <constant name="COMPRESS_NONE" value="0" enum="CompressionMode"> + No compression. </constant> <constant name="COMPRESS_RANGE_CODER" value="1" enum="CompressionMode"> + ENet's buildin range encoding. </constant> <constant name="COMPRESS_FASTLZ" value="2" enum="CompressionMode"> + FastLZ compression. </constant> <constant name="COMPRESS_ZLIB" value="3" enum="CompressionMode"> + zlib compression. </constant> <constant name="COMPRESS_ZSTD" value="4" enum="CompressionMode"> + ZStandard compression. </constant> </constants> </class> diff --git a/modules/freetype/SCsub b/modules/freetype/SCsub index a34a650a4d..8a7c2a773a 100644 --- a/modules/freetype/SCsub +++ b/modules/freetype/SCsub @@ -49,7 +49,6 @@ if env['builtin_freetype']: "src/pshinter/pshinter.c", "src/psnames/psnames.c", "src/raster/raster.c", - "src/sfnt/sfnt.c", "src/smooth/smooth.c", "src/truetype/truetype.c", "src/type1/type1.c", @@ -58,9 +57,18 @@ if env['builtin_freetype']: ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - # Include header for UWP to fix build issues - if "platform" in env and env["platform"] == "uwp": - env.Append(CCFLAGS=['/FI', '"modules/freetype/uwpdef.h"']) + sfnt = thirdparty_dir + 'src/sfnt/sfnt.c' + + if 'platform' in env: + if env['platform'] == 'uwp': + # Include header for UWP to fix build issues + env.Append(CCFLAGS=['/FI', '"modules/freetype/uwpdef.h"']) + elif env['platform'] == 'javascript': + # Forcibly undefine this macro so SIMD is not used in this file, + # since currently unsuported in WASM + sfnt = env.Object(sfnt, CPPFLAGS=['-U__OPTIMIZE__']) + + thirdparty_sources += [sfnt] env.Append(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include"]) diff --git a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml index 998460eee1..be86ff0541 100644 --- a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml +++ b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRInterfaceGDNative" inherits="ARVRInterface" category="Core" version="3.1-dev"> +<class name="ARVRInterfaceGDNative" inherits="ARVRInterface" category="Core" version="3.1"> <brief_description> GDNative wrapper for an ARVR interface </brief_description> diff --git a/modules/gdnative/doc_classes/GDNative.xml b/modules/gdnative/doc_classes/GDNative.xml index 4e87cbf450..ca0457623f 100644 --- a/modules/gdnative/doc_classes/GDNative.xml +++ b/modules/gdnative/doc_classes/GDNative.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GDNative" inherits="Reference" category="Core" version="3.1-dev"> +<class name="GDNative" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/gdnative/doc_classes/GDNativeLibrary.xml b/modules/gdnative/doc_classes/GDNativeLibrary.xml index ca1bae0598..308d8defc3 100644 --- a/modules/gdnative/doc_classes/GDNativeLibrary.xml +++ b/modules/gdnative/doc_classes/GDNativeLibrary.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GDNativeLibrary" inherits="Resource" category="Core" version="3.1-dev"> +<class name="GDNativeLibrary" inherits="Resource" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/gdnative/doc_classes/NativeScript.xml b/modules/gdnative/doc_classes/NativeScript.xml index 6a71cd8d4d..1d3053244b 100644 --- a/modules/gdnative/doc_classes/NativeScript.xml +++ b/modules/gdnative/doc_classes/NativeScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NativeScript" inherits="Script" category="Core" version="3.1-dev"> +<class name="NativeScript" inherits="Script" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/gdnative/doc_classes/PluginScript.xml b/modules/gdnative/doc_classes/PluginScript.xml index 3783d9d0a4..27c6adae3f 100644 --- a/modules/gdnative/doc_classes/PluginScript.xml +++ b/modules/gdnative/doc_classes/PluginScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PluginScript" inherits="Script" category="Core" version="3.1-dev"> +<class name="PluginScript" inherits="Script" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 42c3028f2c..897588385a 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -66,8 +66,169 @@ GDNativeLibrary::GDNativeLibrary() { GDNativeLibrary::~GDNativeLibrary() { } +bool GDNativeLibrary::_set(const StringName &p_name, const Variant &p_property) { + + String name = p_name; + + if (name.begins_with("entry/")) { + String key = name.substr(6, name.length() - 6); + + config_file->set_value("entry", key, p_property); + + set_config_file(config_file); + + return true; + } + + if (name.begins_with("dependency/")) { + String key = name.substr(11, name.length() - 11); + + config_file->set_value("dependencies", key, p_property); + + set_config_file(config_file); + + return true; + } + + return false; +} + +bool GDNativeLibrary::_get(const StringName &p_name, Variant &r_property) const { + String name = p_name; + + if (name.begins_with("entry/")) { + String key = name.substr(6, name.length() - 6); + + r_property = config_file->get_value("entry", key); + + return true; + } + + if (name.begins_with("dependency/")) { + String key = name.substr(11, name.length() - 11); + + r_property = config_file->get_value("dependencies", key); + + return true; + } + + return false; +} + +void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const { + // set entries + List<String> entry_key_list; + + if (config_file->has_section("entry")) + config_file->get_section_keys("entry", &entry_key_list); + + for (List<String>::Element *E = entry_key_list.front(); E; E = E->next()) { + String key = E->get(); + + PropertyInfo prop; + + prop.type = Variant::STRING; + prop.name = "entry/" + key; + + p_list->push_back(prop); + } + + // set dependencies + List<String> dependency_key_list; + + if (config_file->has_section("dependencies")) + config_file->get_section_keys("dependencies", &dependency_key_list); + + for (List<String>::Element *E = dependency_key_list.front(); E; E = E->next()) { + String key = E->get(); + + PropertyInfo prop; + + prop.type = Variant::STRING; + prop.name = "dependency/" + key; + + p_list->push_back(prop); + } +} + +void GDNativeLibrary::set_config_file(Ref<ConfigFile> p_config_file) { + + set_singleton(p_config_file->get_value("general", "singleton", default_singleton)); + set_load_once(p_config_file->get_value("general", "load_once", default_load_once)); + set_symbol_prefix(p_config_file->get_value("general", "symbol_prefix", default_symbol_prefix)); + set_reloadable(p_config_file->get_value("general", "reloadable", default_reloadable)); + + String entry_lib_path; + { + + List<String> entry_keys; + + if (p_config_file->has_section("entry")) + p_config_file->get_section_keys("entry", &entry_keys); + + for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + for (int i = 0; i < tags.size(); i++) { + bool has_feature = OS::get_singleton()->has_feature(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + entry_lib_path = p_config_file->get_value("entry", key); + break; + } + } + + Vector<String> dependency_paths; + { + + List<String> dependency_keys; + + if (p_config_file->has_section("dependencies")) + p_config_file->get_section_keys("dependencies", &dependency_keys); + + for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) { + String key = E->get(); + + Vector<String> tags = key.split("."); + + bool skip = false; + for (int i = 0; i < tags.size(); i++) { + bool has_feature = OS::get_singleton()->has_feature(tags[i]); + + if (!has_feature) { + skip = true; + break; + } + } + + if (skip) { + continue; + } + + dependency_paths = p_config_file->get_value("dependencies", key); + break; + } + } + + current_library_path = entry_lib_path; + current_dependencies = dependency_paths; +} + void GDNativeLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("get_config_file"), &GDNativeLibrary::get_config_file); + ClassDB::bind_method(D_METHOD("set_config_file", "config_file"), &GDNativeLibrary::set_config_file); ClassDB::bind_method(D_METHOD("get_current_library_path"), &GDNativeLibrary::get_current_library_path); ClassDB::bind_method(D_METHOD("get_current_dependencies"), &GDNativeLibrary::get_current_dependencies); @@ -82,6 +243,8 @@ void GDNativeLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("set_symbol_prefix", "symbol_prefix"), &GDNativeLibrary::set_symbol_prefix); ClassDB::bind_method(D_METHOD("set_reloadable", "reloadable"), &GDNativeLibrary::set_reloadable); + ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "config_file", PROPERTY_HINT_RESOURCE_TYPE, "ConfigFile"), "set_config_file", "get_config_file"); + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "load_once"), "set_load_once", "should_load_once"); ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton"), "set_singleton", "is_singleton"); ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "symbol_prefix"), "set_symbol_prefix", "get_symbol_prefix"); @@ -337,73 +500,7 @@ RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_or *r_error = err; } - lib->set_singleton(config->get_value("general", "singleton", default_singleton)); - lib->set_load_once(config->get_value("general", "load_once", default_load_once)); - lib->set_symbol_prefix(config->get_value("general", "symbol_prefix", default_symbol_prefix)); - lib->set_reloadable(config->get_value("general", "reloadable", default_reloadable)); - - String entry_lib_path; - { - - List<String> entry_keys; - config->get_section_keys("entry", &entry_keys); - - for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) { - String key = E->get(); - - Vector<String> tags = key.split("."); - - bool skip = false; - for (int i = 0; i < tags.size(); i++) { - bool has_feature = OS::get_singleton()->has_feature(tags[i]); - - if (!has_feature) { - skip = true; - break; - } - } - - if (skip) { - continue; - } - - entry_lib_path = config->get_value("entry", key); - break; - } - } - - Vector<String> dependency_paths; - { - - List<String> dependency_keys; - config->get_section_keys("dependencies", &dependency_keys); - - for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) { - String key = E->get(); - - Vector<String> tags = key.split("."); - - bool skip = false; - for (int i = 0; i < tags.size(); i++) { - bool has_feature = OS::get_singleton()->has_feature(tags[i]); - - if (!has_feature) { - skip = true; - break; - } - } - - if (skip) { - continue; - } - - dependency_paths = config->get_value("dependencies", key); - break; - } - } - - lib->current_library_path = entry_lib_path; - lib->current_dependencies = dependency_paths; + lib->set_config_file(config); return lib; } diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 3298ea950f..b17bb94f1c 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -66,8 +66,14 @@ public: GDNativeLibrary(); ~GDNativeLibrary(); + virtual bool _set(const StringName &p_name, const Variant &p_property); + virtual bool _get(const StringName &p_name, Variant &r_property) const; + virtual void _get_property_list(List<PropertyInfo> *p_list) const; + _FORCE_INLINE_ Ref<ConfigFile> get_config_file() { return config_file; } + void set_config_file(Ref<ConfigFile> p_config_file); + // things that change per-platform // so there are no setters for this _FORCE_INLINE_ String get_current_library_path() const { diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index a8919f7130..f41c3859bd 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -5822,6 +5822,23 @@ ] }, { + "name": "godot_nativescript_set_global_type_tag", + "return_type": "void", + "arguments": [ + ["int", "p_idx"], + ["const char *", "p_name"], + ["const void *", "p_type_tag"] + ] + }, + { + "name": "godot_nativescript_get_global_type_tag", + "return_type": "const void *", + "arguments": [ + ["int", "p_idx"], + ["const char *", "p_name"] + ] + }, + { "name": "godot_nativescript_set_type_tag", "return_type": "void", "arguments": [ diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index 747328bc41..cfbe16fa7d 100644 --- a/modules/gdnative/include/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -214,16 +214,19 @@ void GDAPI godot_nativescript_set_signal_documentation(void *p_gdnative_handle, // type tag API +void GDAPI godot_nativescript_set_global_type_tag(int p_idx, const char *p_name, const void *p_type_tag); +const void GDAPI *godot_nativescript_get_global_type_tag(int p_idx, const char *p_name); + void GDAPI godot_nativescript_set_type_tag(void *p_gdnative_handle, const char *p_name, const void *p_type_tag); const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object); // instance binding API typedef struct { - void *(*alloc_instance_binding_data)(void *, godot_object *); - void (*free_instance_binding_data)(void *, void *); + GDCALLINGCONV void *(*alloc_instance_binding_data)(void *, const void *, godot_object *); + GDCALLINGCONV void (*free_instance_binding_data)(void *, void *); void *data; - void (*free_func)(void *); + GDCALLINGCONV void (*free_func)(void *); } godot_instance_binding_functions; int GDAPI godot_nativescript_register_instance_binding_data_functions(godot_instance_binding_functions p_binding_functions); diff --git a/modules/gdnative/include/pluginscript/godot_pluginscript.h b/modules/gdnative/include/pluginscript/godot_pluginscript.h index 671be3bbb9..d1671c014e 100644 --- a/modules/gdnative/include/pluginscript/godot_pluginscript.h +++ b/modules/gdnative/include/pluginscript/godot_pluginscript.h @@ -64,7 +64,7 @@ typedef struct { //this is used by script languages that keep a reference counter of their own //you can make make Ref<> not die when it reaches zero, so deleting the reference //depends entirely from the script. - // Note: You can set thoses function pointer to NULL if not needed. + // Note: You can set those function pointer to NULL if not needed. void (*refcount_incremented)(godot_pluginscript_instance_data *p_data); bool (*refcount_decremented)(godot_pluginscript_instance_data *p_data); // return true if it can die } godot_pluginscript_instance_desc; diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp index aea595d0f0..ace2ecac5c 100644 --- a/modules/gdnative/nativescript/godot_nativescript.cpp +++ b/modules/gdnative/nativescript/godot_nativescript.cpp @@ -313,6 +313,14 @@ void GDAPI godot_nativescript_set_signal_documentation(void *p_gdnative_handle, signal->get().documentation = *(String *)&p_documentation; } +void GDAPI godot_nativescript_set_global_type_tag(int p_idx, const char *p_name, const void *p_type_tag) { + NativeScriptLanguage::get_singleton()->set_global_type_tag(p_idx, StringName(p_name), p_type_tag); +} + +const void GDAPI *godot_nativescript_get_global_type_tag(int p_idx, const char *p_name) { + return NativeScriptLanguage::get_singleton()->get_global_type_tag(p_idx, StringName(p_name)); +} + void GDAPI godot_nativescript_set_type_tag(void *p_gdnative_handle, const char *p_name, const void *p_type_tag) { String *s = (String *)p_gdnative_handle; @@ -331,13 +339,11 @@ const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object) const Object *o = (Object *)p_object; if (!o->get_script_instance()) { - ERR_EXPLAIN("Attempted to get type tag on an object without a script!"); - ERR_FAIL_V(NULL); + return NULL; } else { NativeScript *script = Object::cast_to<NativeScript>(o->get_script_instance()->get_script().ptr()); if (!script) { - ERR_EXPLAIN("Attempted to get type tag on an object without a nativescript attached"); - ERR_FAIL_V(NULL); + return NULL; } if (script->get_script_desc()) @@ -347,10 +353,6 @@ const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object) return NULL; } -#ifdef __cplusplus -} -#endif - int GDAPI godot_nativescript_register_instance_binding_data_functions(godot_instance_binding_functions p_binding_functions) { return NativeScriptLanguage::get_singleton()->register_binding_functions(p_binding_functions); } @@ -362,3 +364,7 @@ void GDAPI godot_nativescript_unregister_instance_binding_data_functions(int p_i void GDAPI *godot_nativescript_get_instance_binding_data(int p_idx, godot_object *p_object) { return NativeScriptLanguage::get_singleton()->get_instance_binding_data(p_idx, (Object *)p_object); } + +#ifdef __cplusplus +} +#endif diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index f2e9bef467..d255148e0f 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -55,12 +55,6 @@ #include "editor/editor_node.h" #endif -// -// -// Script stuff -// -// - void NativeScript::_bind_methods() { ClassDB::bind_method(D_METHOD("set_class_name", "class_name"), &NativeScript::set_class_name); ClassDB::bind_method(D_METHOD("get_class_name"), &NativeScript::get_class_name); @@ -528,12 +522,6 @@ NativeScript::~NativeScript() { #endif } - // - // - // ScriptInstance stuff - // - // - #define GET_SCRIPT_DESC() script->get_script_desc() void NativeScriptInstance::_ml_call_reversed(NativeScriptDesc *script_data, const StringName &p_method, const Variant **p_args, int p_argcount) { @@ -872,15 +860,12 @@ NativeScriptInstance::~NativeScriptInstance() { } } -// -// -// ScriptingLanguage stuff -// -// - NativeScriptLanguage *NativeScriptLanguage::singleton; void NativeScriptLanguage::_unload_stuff(bool p_reload) { + + Map<String, Ref<GDNative> > erase_and_unload; + for (Map<String, Map<StringName, NativeScriptDesc> >::Element *L = library_classes.front(); L; L = L->next()) { String lib_path = L->key(); @@ -916,18 +901,6 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) { gdn = E->get(); } - if (gdn.is_valid() && gdn->get_library().is_valid()) { - Ref<GDNativeLibrary> lib = gdn->get_library(); - void *terminate_fn; - Error err = gdn->get_symbol(lib->get_symbol_prefix() + _terminate_call_name, terminate_fn, true); - - if (err == OK) { - void (*terminate)(void *) = (void (*)(void *))terminate_fn; - - terminate((void *)&lib_path); - } - } - for (Map<StringName, NativeScriptDesc>::Element *C = classes.front(); C; C = C->next()) { // free property stuff first @@ -952,12 +925,34 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) { if (C->get().destroy_func.free_func) C->get().destroy_func.free_func(C->get().destroy_func.method_data); } + + erase_and_unload.insert(lib_path, gdn); + } + + for (Map<String, Ref<GDNative> >::Element *E = erase_and_unload.front(); E; E = E->next()) { + String lib_path = E->key(); + Ref<GDNative> gdn = E->get(); + + library_classes.erase(lib_path); + + if (gdn.is_valid() && gdn->get_library().is_valid()) { + Ref<GDNativeLibrary> lib = gdn->get_library(); + void *terminate_fn; + Error err = gdn->get_symbol(lib->get_symbol_prefix() + _terminate_call_name, terminate_fn, true); + + if (err == OK) { + void (*terminate)(void *) = (void (*)(void *))terminate_fn; + + terminate((void *)&lib_path); + } + } } } NativeScriptLanguage::NativeScriptLanguage() { NativeScriptLanguage::singleton = this; #ifndef NO_THREADS + has_objects_to_register = false; mutex = Mutex::create(); #endif } @@ -1182,8 +1177,11 @@ void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_objec } if (!(*binding_data)[p_idx]) { + + const void *global_type_tag = global_type_tags[p_idx].get(p_object->get_class_name()); + // no binding data yet, soooooo alloc new one \o/ - (*binding_data)[p_idx] = binding_functions[p_idx].second.alloc_instance_binding_data(binding_functions[p_idx].second.data, (godot_object *)p_object); + (*binding_data)[p_idx] = binding_functions[p_idx].second.alloc_instance_binding_data(binding_functions[p_idx].second.data, global_type_tag, (godot_object *)p_object); } return (*binding_data)[p_idx]; @@ -1225,6 +1223,27 @@ void NativeScriptLanguage::free_instance_binding_data(void *p_data) { delete &binding_data; } +void NativeScriptLanguage::set_global_type_tag(int p_idx, StringName p_class_name, const void *p_type_tag) { + if (!global_type_tags.has(p_idx)) { + global_type_tags.insert(p_idx, HashMap<StringName, const void *>()); + } + + HashMap<StringName, const void *> &tags = global_type_tags[p_idx]; + + tags.set(p_class_name, p_type_tag); +} + +const void *NativeScriptLanguage::get_global_type_tag(int p_idx, StringName p_class_name) const { + if (!global_type_tags.has(p_idx)) + return NULL; + + const HashMap<StringName, const void *> &tags = global_type_tags[p_idx]; + + const void *tag = tags.get(p_class_name); + + return tag; +} + #ifndef NO_THREADS void NativeScriptLanguage::defer_init_library(Ref<GDNativeLibrary> lib, NativeScript *script) { MutexLock lock(mutex); @@ -1362,6 +1381,7 @@ void NativeReloadNode::_notification(int p_what) { MutexLock lock(NSL->mutex); #endif NSL->_unload_stuff(true); + for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { Ref<GDNative> gdn = L->get(); @@ -1375,7 +1395,6 @@ void NativeReloadNode::_notification(int p_what) { } gdn->terminate(); - NSL->library_classes.erase(L->key()); } unloaded = true; diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 17b6ddc747..68a8126a32 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -36,6 +36,7 @@ #include "core/self_list.h" #include "io/resource_loader.h" #include "io/resource_saver.h" +#include "oa_hash_map.h" #include "ordered_hash_map.h" #include "os/thread_safe.h" #include "scene/main/node.h" @@ -240,6 +241,8 @@ private: Vector<Pair<bool, godot_instance_binding_functions> > binding_functions; Set<Vector<void *> *> binding_instances; + Map<int, HashMap<StringName, const void *> > global_type_tags; + public: // These two maps must only be touched on the main thread Map<String, Map<StringName, NativeScriptDesc> > library_classes; @@ -323,6 +326,9 @@ public: virtual void *alloc_instance_binding_data(Object *p_object); virtual void free_instance_binding_data(void *p_data); + + void set_global_type_tag(int p_idx, StringName p_class_name, const void *p_type_tag); + const void *get_global_type_tag(int p_idx, StringName p_class_name) const; }; inline NativeScriptDesc *NativeScript::get_script_desc() const { diff --git a/modules/gdnative/pluginscript/register_types.cpp b/modules/gdnative/pluginscript/register_types.cpp index 8888f9e157..924abf29df 100644 --- a/modules/gdnative/pluginscript/register_types.cpp +++ b/modules/gdnative/pluginscript/register_types.cpp @@ -64,7 +64,7 @@ static Error _check_language_desc(const godot_pluginscript_language_desc *desc) // desc->make_function is not mandatory // desc->complete_code is not mandatory // desc->auto_indent_code is not mandatory - // desc->add_global_constant is not mandatory + ERR_FAIL_COND_V(!desc->add_global_constant, ERR_BUG); // desc->debug_get_error is not mandatory // desc->debug_get_stack_level_count is not mandatory // desc->debug_get_stack_level_line is not mandatory @@ -78,7 +78,7 @@ static Error _check_language_desc(const godot_pluginscript_language_desc *desc) // desc->profiling_stop is not mandatory // desc->profiling_get_accumulated_data is not mandatory // desc->profiling_get_frame_data is not mandatory - // desc->frame is not mandatory + // desc->profiling_frame is not mandatory ERR_FAIL_COND_V(!desc->script_desc.init, ERR_BUG); ERR_FAIL_COND_V(!desc->script_desc.finish, ERR_BUG); diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml index 0dc69c3688..40a435f459 100644 --- a/modules/gdscript/doc_classes/GDScript.xml +++ b/modules/gdscript/doc_classes/GDScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GDScript" inherits="Script" category="Core" version="3.1-dev"> +<class name="GDScript" inherits="Script" category="Core" version="3.1"> <brief_description> A script implemented in the GDScript programming language. </brief_description> diff --git a/modules/gdscript/doc_classes/GDScriptFunctionState.xml b/modules/gdscript/doc_classes/GDScriptFunctionState.xml index 254d968e1b..c205cedef5 100644 --- a/modules/gdscript/doc_classes/GDScriptFunctionState.xml +++ b/modules/gdscript/doc_classes/GDScriptFunctionState.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GDScriptFunctionState" inherits="Reference" category="Core" version="3.1-dev"> +<class name="GDScriptFunctionState" inherits="Reference" category="Core" version="3.1"> <brief_description> State of a function call after yielding. </brief_description> diff --git a/modules/gdscript/doc_classes/GDScriptNativeClass.xml b/modules/gdscript/doc_classes/GDScriptNativeClass.xml index 1abcc4762f..90935b5c22 100644 --- a/modules/gdscript/doc_classes/GDScriptNativeClass.xml +++ b/modules/gdscript/doc_classes/GDScriptNativeClass.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GDScriptNativeClass" inherits="Reference" category="Core" version="3.1-dev"> +<class name="GDScriptNativeClass" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 1649fb52f2..048948dada 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -181,7 +181,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: //wait, identifier could be a local variable or something else... careful here, must reference properly //as stack may be more interesting to work with - //This could be made much simpler by just indexing "self", but done this way (with custom self-addressing modes) increases peformance a lot. + //This could be made much simpler by just indexing "self", but done this way (with custom self-addressing modes) increases performance a lot. const GDScriptParser::IdentifierNode *in = static_cast<const GDScriptParser::IdentifierNode *>(p_expression); diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 505562324f..87d8fe1bf5 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -60,7 +60,7 @@ Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const Str "# var a = 2\n" + "# var b = \"textvar\"\n\n" + "func _ready():\n" + - "%TS%# Called every time the node is added to the scene.\n" + + "%TS%# Called when the node is added to the scene for the first time.\n" + "%TS%# Initialization here\n" + "%TS%pass\n\n" + "#func _process(delta):\n" + @@ -410,13 +410,11 @@ String GDScriptLanguage::make_function(const String &p_class, const String &p_na String s = "func " + p_name + "("; if (p_args.size()) { - s += " "; for (int i = 0; i < p_args.size(); i++) { if (i > 0) s += ", "; s += p_args[i].get_slice(":", 0); } - s += " "; } s += "):\n" + _get_indentation() + "pass # replace with function body\n"; @@ -2852,7 +2850,24 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol return OK; } } else { - r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT; + /* + // Because get_integer_constant_enum and get_integer_constant dont work on @GlobalScope + // We cannot determine the exact nature of the identifier here + // Otherwise these codes would work + StringName enumName = ClassDB::get_integer_constant_enum("@GlobalScope", p_symbol, true); + if (enumName != NULL) { + r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_ENUM; + r_result.class_name = "@GlobalScope"; + r_result.class_member = enumName; + return OK; + } + else { + r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT; + r_result.class_name = "@GlobalScope"; + r_result.class_member = p_symbol; + return OK; + }*/ + r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_TBD_GLOBALSCOPE; r_result.class_name = "@GlobalScope"; r_result.class_member = p_symbol; return OK; @@ -2915,6 +2930,14 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol return OK; } + StringName enumName = ClassDB::get_integer_constant_enum(t.obj_type, p_symbol, true); + if (enumName != StringName()) { + r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS_ENUM; + r_result.class_name = t.obj_type; + r_result.class_member = enumName; + return OK; + } + bool success; ClassDB::get_integer_constant(t.obj_type, p_symbol, &success); if (success) { diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index a2f449909f..f83bec0c7f 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -1535,15 +1535,21 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar // then the function did yield again after resuming. if (ret.is_ref()) { GDScriptFunctionState *gdfs = Object::cast_to<GDScriptFunctionState>(ret); - if (gdfs && gdfs->function == function) + if (gdfs && gdfs->function == function) { completed = false; + gdfs->previous_state = Ref<GDScriptFunctionState>(this); + } } function = NULL; //cleaned up; state.result = Variant(); if (completed) { - emit_signal("completed", ret); + GDScriptFunctionState *state = this; + while (state != NULL) { + state->emit_signal("completed", ret); + state = *(state->previous_state); + } } return ret; @@ -1591,15 +1597,21 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) { // then the function did yield again after resuming. if (ret.is_ref()) { GDScriptFunctionState *gdfs = Object::cast_to<GDScriptFunctionState>(ret); - if (gdfs && gdfs->function == function) + if (gdfs && gdfs->function == function) { completed = false; + gdfs->previous_state = Ref<GDScriptFunctionState>(this); + } } function = NULL; //cleaned up; state.result = Variant(); if (completed) { - emit_signal("completed", ret); + GDScriptFunctionState *state = this; + while (state != NULL) { + state->emit_signal("completed", ret); + state = *(state->previous_state); + } } return ret; diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 9310444c7a..dff4bdfaf2 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -234,6 +234,7 @@ class GDScriptFunctionState : public Reference { GDScriptFunction *function; GDScriptFunction::CallState state; Variant _signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error); + Ref<GDScriptFunctionState> previous_state; protected: static void _bind_methods(); diff --git a/modules/gdscript/gdscript_highlighter.cpp b/modules/gdscript/gdscript_highlighter.cpp new file mode 100644 index 0000000000..5b8b652c29 --- /dev/null +++ b/modules/gdscript/gdscript_highlighter.cpp @@ -0,0 +1,278 @@ +/*************************************************************************/ +/* gdscript_highlighter.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "gdscript_highlighter.h" +#include "scene/gui/text_edit.h" + +inline bool _is_symbol(CharType c) { + + return is_symbol(c); +} + +static bool _is_text_char(CharType c) { + + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; +} + +static bool _is_whitespace(CharType c) { + return c == '\t' || c == ' '; +} + +static bool _is_char(CharType c) { + + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'; +} + +static bool _is_number(CharType c) { + return (c >= '0' && c <= '9'); +} + +static bool _is_hex_symbol(CharType c) { + return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); +} + +Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) { + Map<int, TextEdit::HighlighterInfo> color_map; + + bool prev_is_char = false; + bool prev_is_number = false; + bool in_keyword = false; + bool in_word = false; + bool in_function_name = false; + bool in_member_variable = false; + bool is_hex_notation = false; + Color keyword_color; + Color color; + + int in_region = -1; + int deregion = 0; + for (int i = 0; i < p_line; i++) { + int ending_color_region = text_editor->_get_line_ending_color_region(i); + if (in_region == -1) { + in_region = ending_color_region; + } else if (in_region == ending_color_region) { + in_region = -1; + } else { + const Map<int, TextEdit::Text::ColorRegionInfo> &cri_map = text_editor->_get_line_color_region_info(i); + for (const Map<int, TextEdit::Text::ColorRegionInfo>::Element *E = cri_map.front(); E; E = E->next()) { + const TextEdit::Text::ColorRegionInfo &cri = E->get(); + if (cri.region == in_region) { + in_region = -1; + } + } + } + } + + const Map<int, TextEdit::Text::ColorRegionInfo> cri_map = text_editor->_get_line_color_region_info(p_line); + const String &str = text_editor->get_line(p_line); + Color prev_color; + for (int j = 0; j < str.length(); j++) { + TextEdit::HighlighterInfo highlighter_info; + + if (deregion > 0) { + deregion--; + if (deregion == 0) { + in_region = -1; + } + } + + if (deregion != 0) { + if (color != prev_color) { + prev_color = color; + highlighter_info.color = color; + color_map[j] = highlighter_info; + } + continue; + } + + color = font_color; + + bool is_char = _is_text_char(str[j]); + bool is_symbol = _is_symbol(str[j]); + bool is_number = _is_number(str[j]); + + // allow ABCDEF in hex notation + if (is_hex_notation && (_is_hex_symbol(str[j]) || is_number)) { + is_number = true; + } else { + is_hex_notation = false; + } + + // check for dot or underscore or 'x' for hex notation in floating point number + if ((str[j] == '.' || str[j] == 'x' || str[j] == '_') && !in_word && prev_is_number && !is_number) { + is_number = true; + is_symbol = false; + is_char = false; + + if (str[j] == 'x' && str[j - 1] == '0') { + is_hex_notation = true; + } + } + + if (!in_word && _is_char(str[j]) && !is_number) { + in_word = true; + } + + if ((in_keyword || in_word) && !is_hex_notation) { + is_number = false; + } + + if (is_symbol && str[j] != '.' && in_word) { + in_word = false; + } + + if (is_symbol && cri_map.has(j)) { + const TextEdit::Text::ColorRegionInfo &cri = cri_map[j]; + + if (in_region == -1) { + if (!cri.end) { + in_region = cri.region; + } + } else { + TextEdit::ColorRegion cr = text_editor->_get_color_region(cri.region); + if (in_region == cri.region && !cr.line_only) { //ignore otherwise + if (cri.end || cr.eq) { + deregion = cr.eq ? cr.begin_key.length() : cr.end_key.length(); + } + } + } + } + + if (!is_char) { + in_keyword = false; + } + + if (in_region == -1 && !in_keyword && is_char && !prev_is_char) { + + int to = j; + while (to < str.length() && _is_text_char(str[to])) + to++; + + String word = str.substr(j, to - j); + Color col = Color(); + if (text_editor->has_keyword_color(word)) { + col = text_editor->get_keyword_color(word); + } else if (text_editor->has_member_color(word)) { + col = text_editor->get_member_color(word); + for (int k = j - 1; k >= 0; k--) { + if (str[k] == '.') { + col = Color(); //member indexing not allowed + break; + } else if (str[k] > 32) { + break; + } + } + } + + if (col != Color()) { + in_keyword = true; + keyword_color = col; + } + } + + if (!in_function_name && in_word && !in_keyword) { + + int k = j; + while (k < str.length() && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { + k++; + } + + // check for space between name and bracket + while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) { + k++; + } + + if (str[k] == '(') { + in_function_name = true; + } + } + + if (!in_function_name && !in_member_variable && !in_keyword && !is_number && in_word) { + int k = j; + while (k > 0 && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { + k--; + } + + if (str[k] == '.') { + in_member_variable = true; + } + } + + if (is_symbol) { + in_function_name = false; + in_member_variable = false; + } + + if (in_region >= 0) + color = text_editor->_get_color_region(in_region).color; + else if (in_keyword) + color = keyword_color; + else if (in_member_variable) + color = member_color; + else if (in_function_name) + color = function_color; + else if (is_symbol) + color = symbol_color; + else if (is_number) + color = number_color; + + prev_is_char = is_char; + prev_is_number = is_number; + + if (color != prev_color) { + prev_color = color; + highlighter_info.color = color; + color_map[j] = highlighter_info; + } + } + return color_map; +} + +String GDScriptSyntaxHighlighter::get_name() { + return "GDScript"; +} + +List<String> GDScriptSyntaxHighlighter::get_supported_languages() { + List<String> languages; + languages.push_back("GDScript"); + return languages; +} + +void GDScriptSyntaxHighlighter::_update_cache() { + font_color = text_editor->get_color("font_color"); + symbol_color = text_editor->get_color("symbol_color"); + function_color = text_editor->get_color("function_color"); + number_color = text_editor->get_color("number_color"); + member_color = text_editor->get_color("member_variable_color"); +} + +SyntaxHighlighter *GDScriptSyntaxHighlighter::create() { + return memnew(GDScriptSyntaxHighlighter); +} diff --git a/platform/javascript/power_javascript.cpp b/modules/gdscript/gdscript_highlighter.h index 5241644dbc..ef1bdd4103 100644 --- a/platform/javascript/power_javascript.cpp +++ b/modules/gdscript/gdscript_highlighter.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* power_javascript.cpp */ +/* gdscript_highlighter.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,46 +28,29 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "power_javascript.h" -#include "error_macros.h" +#ifndef GDSCRIPT_HIGHLIGHTER_H +#define GDSCRIPT_HIGHLIGHTER_H -bool PowerJavascript::UpdatePowerInfo() { - // TODO Javascript implementation - return false; -} +#include "scene/gui/text_edit.h" -OS::PowerState PowerJavascript::get_power_state() { - if (UpdatePowerInfo()) { - return power_state; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to POWERSTATE_UNKNOWN"); - return OS::POWERSTATE_UNKNOWN; - } -} +class GDScriptSyntaxHighlighter : public SyntaxHighlighter { +private: + // colours + Color font_color; + Color symbol_color; + Color function_color; + Color built_in_type_color; + Color number_color; + Color member_color; -int PowerJavascript::get_power_seconds_left() { - if (UpdatePowerInfo()) { - return nsecs_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; - } -} +public: + static SyntaxHighlighter *create(); -int PowerJavascript::get_power_percent_left() { - if (UpdatePowerInfo()) { - return percent_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; - } -} + virtual void _update_cache(); + virtual Map<int, TextEdit::HighlighterInfo> _get_line_syntax_highlighting(int p_line); -PowerJavascript::PowerJavascript() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} + virtual String get_name(); + virtual List<String> get_supported_languages(); +}; -PowerJavascript::~PowerJavascript() { -} +#endif // GDSCRIPT_HIGHLIGHTER_H diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index cd752a786c..435bc327dc 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -461,18 +461,21 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } else if (!for_completion || FileAccess::exists(path)) { res = ResourceLoader::load(path); } - if (!res.is_valid()) { - _set_error("Can't preload resource at path: " + path); - return NULL; - } } else { if (!FileAccess::exists(path)) { _set_error("Can't preload resource at path: " + path); return NULL; + } else if (ScriptCodeCompletionCache::get_singleton()) { + res = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(path); } } + if (!res.is_valid()) { + _set_error("Can't preload resource at path: " + path); + return NULL; + } + if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { _set_error("Expected ')' after 'preload' path"); return NULL; @@ -4098,7 +4101,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { ConstantNode *cn = static_cast<ConstantNode *>(subexpr); if (cn->value.get_type() == Variant::NIL) { - _set_error("Can't accept a null constant expression for infering export type."); + _set_error("Can't accept a null constant expression for inferring export type."); return; } member._export.type = cn->value.get_type(); @@ -4234,7 +4237,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } break; case GDScriptTokenizer::TK_PR_ENUM: { - //mutiple constant declarations.. + //multiple constant declarations.. int last_assign = -1; // Incremented by 1 right before the assingment. String enum_name; diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index 95efcda80f..85c94c3596 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -31,6 +31,7 @@ #include "register_types.h" #include "gdscript.h" +#include "gdscript_highlighter.h" #include "gdscript_tokenizer.h" #include "io/file_access_encrypted.h" #include "io/resource_loader.h" @@ -92,6 +93,7 @@ void register_gdscript_types() { ResourceSaver::add_resource_format_saver(resource_saver_gd); #ifdef TOOLS_ENABLED + ScriptEditor::register_create_syntax_highlighter_function(GDScriptSyntaxHighlighter::create); EditorNode::add_init_callback(_editor_init); #endif } diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index 36d4d7cb59..bb652f3bdf 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GridMap" inherits="Spatial" category="Core" version="3.1-dev"> +<class name="GridMap" inherits="Spatial" category="Core" version="3.1"> <brief_description> Node for 3D tile-based maps. </brief_description> diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 34d51b51e2..f523eef895 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -101,8 +101,8 @@ void GridMapEditor::_menu_option(int p_option) { } if (edit_axis != new_axis) { - int item1 = options->get_popup()->get_item_id(MENU_OPTION_NEXT_LEVEL); - int item2 = options->get_popup()->get_item_id(MENU_OPTION_PREV_LEVEL); + int item1 = options->get_popup()->get_item_index(MENU_OPTION_NEXT_LEVEL); + int item2 = options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL); if (edit_axis == Vector3::AXIS_Y) { options->get_popup()->set_item_text(item1, TTR("Next Plane")); options->get_popup()->set_item_text(item2, TTR("Previous Plane")); @@ -641,12 +641,21 @@ bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<Inpu Ref<InputEventPanGesture> pan_gesture = p_event; if (pan_gesture.is_valid()) { - if (pan_gesture->get_command() || pan_gesture->get_shift()) { - const real_t delta = pan_gesture->get_delta().y; - floor->set_value(floor->get_value() + SGN(delta)); + if (pan_gesture->get_alt() && (pan_gesture->get_command() || pan_gesture->get_shift())) { + const real_t delta = pan_gesture->get_delta().y * 0.5; + accumulated_floor_delta += delta; + int step = 0; + if (ABS(accumulated_floor_delta) > 1.0) { + step = SGN(accumulated_floor_delta); + accumulated_floor_delta -= step; + } + if (step) { + floor->set_value(floor->get_value() + step); + } return true; } } + accumulated_floor_delta = 0.0; return false; } @@ -770,7 +779,7 @@ void GridMapEditor::edit(GridMap *p_gridmap) { set_process(true); - Vector3 edited_floor = p_gridmap->get_meta("_editor_floor_"); + Vector3 edited_floor = p_gridmap->has_meta("_editor_floor_") ? p_gridmap->get_meta("_editor_floor_") : Variant(); clip_mode = p_gridmap->has_meta("_editor_clip_") ? ClipMode(p_gridmap->get_meta("_editor_clip_").operator int()) : CLIP_DISABLED; for (int i = 0; i < 3; i++) { @@ -1037,14 +1046,14 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { options->get_popup()->add_item(TTR("Previous Floor"), MENU_OPTION_PREV_LEVEL, KEY_Q); options->get_popup()->add_item(TTR("Next Floor"), MENU_OPTION_NEXT_LEVEL, KEY_E); options->get_popup()->add_separator(); - options->get_popup()->add_check_item(TTR("Clip Disabled"), MENU_OPTION_CLIP_DISABLED); + options->get_popup()->add_radio_check_item(TTR("Clip Disabled"), MENU_OPTION_CLIP_DISABLED); options->get_popup()->set_item_checked(options->get_popup()->get_item_index(MENU_OPTION_CLIP_DISABLED), true); - options->get_popup()->add_check_item(TTR("Clip Above"), MENU_OPTION_CLIP_ABOVE); - options->get_popup()->add_check_item(TTR("Clip Below"), MENU_OPTION_CLIP_BELOW); + options->get_popup()->add_radio_check_item(TTR("Clip Above"), MENU_OPTION_CLIP_ABOVE); + options->get_popup()->add_radio_check_item(TTR("Clip Below"), MENU_OPTION_CLIP_BELOW); options->get_popup()->add_separator(); - options->get_popup()->add_check_item(TTR("Edit X Axis"), MENU_OPTION_X_AXIS, KEY_Z); - options->get_popup()->add_check_item(TTR("Edit Y Axis"), MENU_OPTION_Y_AXIS, KEY_X); - options->get_popup()->add_check_item(TTR("Edit Z Axis"), MENU_OPTION_Z_AXIS, KEY_C); + options->get_popup()->add_radio_check_item(TTR("Edit X Axis"), MENU_OPTION_X_AXIS, KEY_Z); + options->get_popup()->add_radio_check_item(TTR("Edit Y Axis"), MENU_OPTION_Y_AXIS, KEY_X); + options->get_popup()->add_radio_check_item(TTR("Edit Z Axis"), MENU_OPTION_Z_AXIS, KEY_C); options->get_popup()->set_item_checked(options->get_popup()->get_item_index(MENU_OPTION_Y_AXIS), true); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Cursor Rotate X"), MENU_OPTION_CURSOR_ROTATE_X, KEY_A); @@ -1247,6 +1256,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { selection.active = false; updating = false; + accumulated_floor_delta = 0.0; } GridMapEditor::~GridMapEditor() { @@ -1259,9 +1269,10 @@ GridMapEditor::~GridMapEditor() { VisualServer::get_singleton()->free(grid_instance[i]); if (cursor_instance.is_valid()) VisualServer::get_singleton()->free(cursor_instance); - if (selection_level_instance[i].is_valid()) { + if (selection_level_instance[i].is_valid()) VisualServer::get_singleton()->free(selection_level_instance[i]); - } + if (selection_level_mesh[i].is_valid()) + VisualServer::get_singleton()->free(selection_level_mesh[i]); } VisualServer::get_singleton()->free(selection_mesh); diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 9651770528..f79d9aefa0 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -76,6 +76,7 @@ class GridMapEditor : public VBoxContainer { Panel *panel; MenuButton *options; SpinBox *floor; + double accumulated_floor_delta; ToolButton *mode_thumbnail; ToolButton *mode_list; HBoxContainer *spatial_editor_hb; diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp index 3cc362b5d6..d592c19b97 100644 --- a/modules/hdr/image_loader_hdr.cpp +++ b/modules/hdr/image_loader_hdr.cpp @@ -42,14 +42,18 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force ERR_FAIL_COND_V(header != "#?RADIANCE" && header != "#?RGBE", ERR_FILE_UNRECOGNIZED); while (true) { - String format = f->get_token(); + String line = f->get_line(); ERR_FAIL_COND_V(f->eof_reached(), ERR_FILE_UNRECOGNIZED); - if (format.begins_with("FORMAT=") && format != "FORMAT=32-bit_rle_rgbe") { - ERR_EXPLAIN("Only 32-bit_rle_rgbe is supported for .hdr files."); - return ERR_FILE_UNRECOGNIZED; - } - if (format == "FORMAT=32-bit_rle_rgbe") + if (line == "") // empty line indicates end of header break; + if (line.begins_with("FORMAT=")) { // leave option to implement other commands + if (line != "FORMAT=32-bit_rle_rgbe") { + ERR_EXPLAIN("Only 32-bit_rle_rgbe is supported for HDR files."); + return ERR_FILE_UNRECOGNIZED; + } + } else if (!line.begins_with("#")) { // not comment + WARN_PRINTS("Ignoring unsupported header information in HDR : " + line); + } } String token = f->get_token(); diff --git a/modules/mbedtls/SCsub b/modules/mbedtls/SCsub index b846ae38ad..38198c9105 100755 --- a/modules/mbedtls/SCsub +++ b/modules/mbedtls/SCsub @@ -85,7 +85,7 @@ if env['builtin_mbedtls']: thirdparty_dir = "#thirdparty/mbedtls/library/" thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env_mbed_tls.add_source_files(env.modules_sources, thirdparty_sources) - env_mbed_tls.Append(CPPPATH=["#thirdparty/mbedtls/include/"]) + env_mbed_tls.Prepend(CPPPATH=["#thirdparty/mbedtls/include/"]) # Module sources env_mbed_tls.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/mbedtls/stream_peer_mbed_tls.cpp b/modules/mbedtls/stream_peer_mbed_tls.cpp index 4135eb40ff..a63e53ec1f 100755 --- a/modules/mbedtls/stream_peer_mbed_tls.cpp +++ b/modules/mbedtls/stream_peer_mbed_tls.cpp @@ -293,28 +293,10 @@ void StreamPeerMbedTLS::initialize_ssl() { mbedtls_debug_set_threshold(1); #endif - String certs_path = GLOBAL_DEF("network/ssl/certificates", ""); - ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt")); - - if (certs_path != "") { - - FileAccess *f = FileAccess::open(certs_path, FileAccess::READ); - if (f) { - PoolByteArray arr; - int flen = f->get_len(); - arr.resize(flen + 1); - { - PoolByteArray::Write w = arr.write(); - f->get_buffer(w.ptr(), flen); - w[flen] = 0; //end f string - } - - memdelete(f); - - _load_certs(arr); - print_line("Loaded certs from '" + certs_path); - } - } + PoolByteArray cert_array = StreamPeerSSL::get_project_cert_array(); + + if (cert_array.size() > 0) + _load_certs(cert_array); available = true; } diff --git a/modules/mbedtls/stream_peer_mbed_tls.h b/modules/mbedtls/stream_peer_mbed_tls.h index ce17614d85..2b96a194a1 100755 --- a/modules/mbedtls/stream_peer_mbed_tls.h +++ b/modules/mbedtls/stream_peer_mbed_tls.h @@ -32,8 +32,6 @@ #define STREAM_PEER_OPEN_SSL_H #include "io/stream_peer_ssl.h" -#include "os/file_access.h" -#include "project_settings.h" #include "mbedtls/config.h" #include "mbedtls/ctr_drbg.h" diff --git a/modules/mobile_vr/config.py b/modules/mobile_vr/config.py index 4e1155f0c6..aa8ef111d3 100644 --- a/modules/mobile_vr/config.py +++ b/modules/mobile_vr/config.py @@ -1,6 +1,6 @@ def can_build(platform): # should probably change this to only be true on iOS and Android - return True + return False def configure(env): pass diff --git a/modules/mobile_vr/doc_classes/MobileVRInterface.xml b/modules/mobile_vr/doc_classes/MobileVRInterface.xml index d3f2548320..359d654433 100644 --- a/modules/mobile_vr/doc_classes/MobileVRInterface.xml +++ b/modules/mobile_vr/doc_classes/MobileVRInterface.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MobileVRInterface" inherits="ARVRInterface" category="Core" version="3.1-dev"> +<class name="MobileVRInterface" inherits="ARVRInterface" category="Core" version="3.1"> <brief_description> Generic mobile VR implementation </brief_description> diff --git a/modules/mono/SCsub b/modules/mono/SCsub index aa8626e6da..a1dfcf6377 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -31,11 +31,18 @@ def make_cs_files_header(src, dst): if i > 0: header.write(', ') header.write(byte_to_str(buf[buf_idx])) - inserted_files += '\tr_files.insert(\"' + file + '\", ' \ + inserted_files += '\tr_files.insert("' + file + '", ' \ 'CompressedFile(_cs_' + name + '_compressed_size, ' \ '_cs_' + name + '_uncompressed_size, ' \ '_cs_' + name + '_compressed));\n' header.write(' };\n') + version_file = os.path.join(src, 'VERSION.txt') + with open(version_file, 'r') as content_file: + try: + glue_version = int(content_file.read()) # make sure the format is valid + header.write('\n#define CS_GLUE_VERSION UINT32_C(' + str(glue_version) + ')\n') + except ValueError: + raise ValueError('Invalid C# glue version in: ' + version_file) header.write('\nstruct CompressedFile\n' '{\n' '\tint compressed_size;\n' '\tint uncompressed_size;\n' '\tconst unsigned char* data;\n' '\n\tCompressedFile(int p_comp_size, int p_uncomp_size, const unsigned char* p_data)\n' @@ -80,23 +87,23 @@ def find_msbuild_unix(filename): import sys hint_dirs = ['/opt/novell/mono/bin'] - if sys.platform == "darwin": + if sys.platform == 'darwin': hint_dirs = ['/Library/Frameworks/Mono.framework/Versions/Current/bin'] + hint_dirs for hint_dir in hint_dirs: hint_path = os.path.join(hint_dir, filename) if os.path.isfile(hint_path): return hint_path - elif os.path.isfile(hint_path + ".exe"): - return hint_path + ".exe" + elif os.path.isfile(hint_path + '.exe'): + return hint_path + '.exe' - for hint_dir in os.environ["PATH"].split(os.pathsep): + for hint_dir in os.environ['PATH'].split(os.pathsep): hint_dir = hint_dir.strip('"') hint_path = os.path.join(hint_dir, filename) if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK): return hint_path - if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK): - return hint_path + ".exe" + if os.path.isfile(hint_path + '.exe') and os.access(hint_path + '.exe', os.X_OK): + return hint_path + '.exe' return None @@ -152,7 +159,7 @@ def mono_build_solution(source, target, env): xbuild_fallback = env['xbuild_fallback'] if xbuild_fallback and os.name == 'nt': - print("Option 'xbuild_fallback' not supported on Windows") + print('Option \'xbuild_fallback\' not supported on Windows') xbuild_fallback = False if xbuild_fallback: @@ -202,10 +209,16 @@ def mono_build_solution(source, target, env): copyfile(os.path.join(src_dir, asm_file), os.path.join(dst_dir, asm_file)) +output_dir = Dir('#bin').abspath +assemblies_output_dir = Dir(env['mono_assemblies_output_dir']).abspath -mono_sln_builder = Builder(action = mono_build_solution) +mono_sln_builder = Builder(action=mono_build_solution) env_mono.Append(BUILDERS={'MonoBuildSolution': mono_sln_builder}) env_mono.MonoBuildSolution( - os.path.join(Dir('#bin').abspath, 'GodotSharpTools.dll'), + os.path.join(assemblies_output_dir, 'GodotSharpTools.dll'), 'editor/GodotSharpTools/GodotSharpTools.sln' ) + +if os.path.normpath(output_dir) != os.path.normpath(assemblies_output_dir): + rel_assemblies_output_dir = os.path.relpath(assemblies_output_dir, output_dir) + env_mono.Append(CPPDEFINES={'GD_MONO_EDITOR_ASSEMBLIES_DIR': rel_assemblies_output_dir}) diff --git a/modules/mono/config.py b/modules/mono/config.py index 7c1846dcc2..831d849ea6 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -2,8 +2,9 @@ import imp import os import sys +import subprocess -from SCons.Script import BoolVariable, Environment, Variables +from SCons.Script import BoolVariable, Dir, Environment, PathVariable, Variables monoreg = imp.load_source('mono_reg_utils', 'modules/mono/mono_reg_utils.py') @@ -29,20 +30,16 @@ def is_enabled(): return False -def copy_file_no_replace(src_dir, dst_dir, name): +def copy_file(src_dir, dst_dir, name): from shutil import copyfile src_path = os.path.join(src_dir, name) dst_path = os.path.join(dst_dir, name) - need_copy = True if not os.path.isdir(dst_dir): os.mkdir(dst_dir) - elif os.path.exists(dst_path): - need_copy = False - if need_copy: - copyfile(src_path, dst_path) + copyfile(src_path, dst_path) def configure(env): @@ -51,11 +48,13 @@ def configure(env): envvars = Variables() envvars.Add(BoolVariable('mono_static', 'Statically link mono', False)) + envvars.Add(PathVariable('mono_assemblies_output_dir', 'Path to the assemblies output directory', '#bin', PathVariable.PathIsDirCreate)) envvars.Update(env) bits = env['bits'] mono_static = env['mono_static'] + assemblies_output_dir = Dir(env['mono_assemblies_output_dir']).abspath mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0'] @@ -99,11 +98,14 @@ def configure(env): if not mono_dll_name: raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path) - copy_file_no_replace(mono_bin_path, 'bin', mono_dll_name + '.dll') + copy_file(mono_bin_path, 'bin', mono_dll_name + '.dll') + + copy_file(os.path.join(mono_lib_path, 'mono', '4.5'), assemblies_output_dir, 'mscorlib.dll') else: sharedlib_ext = '.dylib' if sys.platform == 'darwin' else '.so' mono_root = '' + mono_lib_path = '' if bits == '32': if os.getenv('MONO32_PREFIX'): @@ -148,7 +150,9 @@ def configure(env): if not mono_so_name: raise RuntimeError('Could not find mono shared library in: ' + mono_lib_path) - copy_file_no_replace(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext) + copy_file(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext) + + copy_file(os.path.join(mono_lib_path, 'mono', '4.5'), assemblies_output_dir, 'mscorlib.dll') else: if mono_static: raise RuntimeError('mono-static: Not supported with pkg-config. Specify a mono prefix manually') @@ -157,6 +161,7 @@ def configure(env): mono_lib_path = '' mono_so_name = '' + mono_prefix = subprocess.check_output(["pkg-config", "mono-2", "--variable=prefix"]).decode("utf8").strip() tmpenv = Environment() tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH')) @@ -172,7 +177,8 @@ def configure(env): if not mono_so_name: raise RuntimeError('Could not find mono shared library in: ' + str(tmpenv['LIBPATH'])) - copy_file_no_replace(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext) + copy_file(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext) + copy_file(os.path.join(mono_prefix, 'lib', 'mono', '4.5'), assemblies_output_dir, 'mscorlib.dll') env.Append(LINKFLAGS='-rdynamic') diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index fb45136575..1d0afa7f2d 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -118,6 +118,8 @@ void CSharpLanguage::init() { #ifdef TOOLS_ENABLED EditorNode::add_init_callback(&gdsharp_editor_init_callback); + + GLOBAL_DEF("mono/export/include_scripts_content", true); #endif } @@ -280,6 +282,15 @@ void CSharpLanguage::get_string_delimiters(List<String> *p_delimiters) const { p_delimiters->push_back("@\" \""); // verbatim string literal } +static String get_base_class_name(const String &p_base_class_name, const String p_class_name) { + + String base_class = p_base_class_name; + if (p_class_name == base_class) { + base_class = "Godot." + base_class; + } + return base_class; +} + Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const { String script_template = "using " BINDINGS_NAMESPACE ";\n" @@ -306,7 +317,8 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin "// }\n" "}\n"; - script_template = script_template.replace("%BASE_CLASS_NAME%", p_base_class_name) + String base_class_name = get_base_class_name(p_base_class_name, p_class_name); + script_template = script_template.replace("%BASE_CLASS_NAME%", base_class_name) .replace("%CLASS_NAME%", p_class_name); Ref<CSharpScript> script; @@ -325,12 +337,24 @@ bool CSharpLanguage::is_using_templates() { void CSharpLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) { String src = p_script->get_source_code(); - src = src.replace("%BASE%", p_base_class_name) + String base_class_name = get_base_class_name(p_base_class_name, p_class_name); + src = src.replace("%BASE%", base_class_name) .replace("%CLASS%", p_class_name) .replace("%TS%", _get_indentation()); p_script->set_source_code(src); } +String CSharpLanguage::validate_path(const String &p_path) const { + + String class_name = p_path.get_file().get_basename(); + List<String> keywords; + get_reserved_words(&keywords); + if (keywords.find(class_name)) { + return TTR("Class name can't be a reserved keyword"); + } + return ""; +} + Script *CSharpLanguage::create_script() const { return memnew(CSharpScript); @@ -454,7 +478,7 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info() #ifdef DEBUG_ENABLED // Printing an error here will result in endless recursion, so we must be careful - if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_api_assembly() || !GDMonoUtils::mono_cache.corlib_cache_updated) + if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_core_api_assembly() || !GDMonoUtils::mono_cache.corlib_cache_updated) return Vector<StackInfo>(); MonoObject *stack_trace = mono_object_new(mono_domain_get(), CACHED_CLASS(System_Diagnostics_StackTrace)->get_mono_ptr()); @@ -1550,7 +1574,6 @@ bool CSharpScript::_update_exports() { } bool CSharpScript::_update_signals() { -#ifdef TOOLS_ENABLED if (!valid) return false; @@ -1581,8 +1604,6 @@ bool CSharpScript::_update_signals() { } return changed; -#endif - return false; } bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Vector<Argument> ¶ms) { @@ -2135,9 +2156,7 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const { } void CSharpScript::update_signals() { -#ifdef TOOLS_ENABLED _update_signals(); -#endif } Ref<Script> CSharpScript::get_base_script() const { diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index ffb1d2e0f4..8666149111 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -90,15 +90,15 @@ class CSharpScript : public Script { Variant::Type type; }; + Map<StringName, Vector<Argument> > _signals; + bool signals_invalidated; + #ifdef TOOLS_ENABLED List<PropertyInfo> exported_members_cache; // members_cache Map<StringName, Variant> exported_members_defval_cache; // member_default_values_cache Set<PlaceHolderScriptInstance *> placeholders; bool source_changed_cache; bool exports_invalidated; - Map<StringName, Vector<Argument> > _signals; - bool signals_invalidated; - void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames); virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder); #endif @@ -294,6 +294,7 @@ public: virtual bool is_using_templates(); virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script); /* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const { return true; } + virtual String validate_path(const String &p_path) const; virtual Script *create_script() const; virtual bool has_named_classes() const; virtual bool supports_builtin_mode() const; diff --git a/modules/mono/doc_classes/@C#.xml b/modules/mono/doc_classes/@C#.xml index 0c2bb948ea..082bc30fd8 100644 --- a/modules/mono/doc_classes/@C#.xml +++ b/modules/mono/doc_classes/@C#.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="@C#" category="Core" version="3.1-dev"> +<class name="@C#" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/mono/doc_classes/CSharpScript.xml b/modules/mono/doc_classes/CSharpScript.xml index 9bd57f1d4d..a1f7399653 100644 --- a/modules/mono/doc_classes/CSharpScript.xml +++ b/modules/mono/doc_classes/CSharpScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="CSharpScript" inherits="Script" category="Core" version="3.1-dev"> +<class name="CSharpScript" inherits="Script" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/mono/doc_classes/GodotSharp.xml b/modules/mono/doc_classes/GodotSharp.xml index 51f07523e7..985c66464b 100644 --- a/modules/mono/doc_classes/GodotSharp.xml +++ b/modules/mono/doc_classes/GodotSharp.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="GodotSharp" inherits="Object" category="Core" version="3.1-dev"> +<class name="GodotSharp" inherits="Object" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 952e033565..a210b8e480 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -70,8 +70,6 @@ #define LOCAL_RET "ret" -#define CS_CLASS_NATIVECALLS "NativeCalls" -#define CS_CLASS_NATIVECALLS_EDITOR "EditorNativeCalls" #define CS_FIELD_MEMORYOWN "memoryOwn" #define CS_PARAM_METHODBIND "method" #define CS_PARAM_INSTANCE "ptr" @@ -105,6 +103,8 @@ #define C_METHOD_MANAGED_TO_DICT C_NS_MONOMARSHAL "::mono_object_to_Dictionary" #define C_METHOD_MANAGED_FROM_DICT C_NS_MONOMARSHAL "::Dictionary_to_mono_object" +#define BINDINGS_GENERATOR_VERSION UINT32_C(2) + const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in = %1;\n"; bool BindingsGenerator::verbose_output = false; @@ -529,7 +529,15 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_output_dir, bo "using System.Collections.Generic;\n" "\n"); cs_icalls_content.push_back("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK); - cs_icalls_content.push_back(INDENT1 "internal static class " CS_CLASS_NATIVECALLS "\n" INDENT1 OPEN_BLOCK); + cs_icalls_content.push_back(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS "\n" INDENT1 OPEN_BLOCK); + + cs_icalls_content.push_back(INDENT2 "internal static ulong godot_api_hash = "); + cs_icalls_content.push_back(String::num_uint64(GDMono::get_singleton()->get_api_core_hash()) + ";\n"); + cs_icalls_content.push_back(INDENT2 "internal static uint bindings_version = "); + cs_icalls_content.push_back(String::num_uint64(BINDINGS_GENERATOR_VERSION) + ";\n"); + cs_icalls_content.push_back(INDENT2 "internal static uint cs_glue_version = "); + cs_icalls_content.push_back(String::num_uint64(CS_GLUE_VERSION) + ";\n"); + cs_icalls_content.push_back("\n"); #define ADD_INTERNAL_CALL(m_icall) \ if (!m_icall.editor_only) { \ @@ -551,7 +559,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_output_dir, bo cs_icalls_content.push_back(INDENT1 CLOSE_BLOCK CLOSE_BLOCK); - String internal_methods_file = path_join(core_dir, CS_CLASS_NATIVECALLS ".cs"); + String internal_methods_file = path_join(core_dir, BINDINGS_CLASS_NATIVECALLS ".cs"); Error err = _save_file(internal_methods_file, cs_icalls_content); if (err != OK) @@ -626,7 +634,15 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_output_dir, "using System.Collections.Generic;\n" "\n"); cs_icalls_content.push_back("namespace " BINDINGS_NAMESPACE "\n" OPEN_BLOCK); - cs_icalls_content.push_back(INDENT1 "internal static class " CS_CLASS_NATIVECALLS_EDITOR "\n" INDENT1 OPEN_BLOCK); + cs_icalls_content.push_back(INDENT1 "internal static class " BINDINGS_CLASS_NATIVECALLS_EDITOR "\n" INDENT1 OPEN_BLOCK); + + cs_icalls_content.push_back(INDENT2 "internal static ulong godot_api_hash = "); + cs_icalls_content.push_back(String::num_uint64(GDMono::get_singleton()->get_api_editor_hash()) + ";\n"); + cs_icalls_content.push_back(INDENT2 "internal static uint bindings_version = "); + cs_icalls_content.push_back(String::num_uint64(BINDINGS_GENERATOR_VERSION) + ";\n"); + cs_icalls_content.push_back(INDENT2 "internal static uint cs_glue_version = "); + cs_icalls_content.push_back(String::num_uint64(CS_GLUE_VERSION) + ";\n"); + cs_icalls_content.push_back("\n"); #define ADD_INTERNAL_CALL(m_icall) \ if (m_icall.editor_only) { \ @@ -648,7 +664,7 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_output_dir, cs_icalls_content.push_back(INDENT1 CLOSE_BLOCK CLOSE_BLOCK); - String internal_methods_file = path_join(core_dir, CS_CLASS_NATIVECALLS_EDITOR ".cs"); + String internal_methods_file = path_join(core_dir, BINDINGS_CLASS_NATIVECALLS_EDITOR ".cs"); Error err = _save_file(internal_methods_file, cs_icalls_content); if (err != OK) @@ -714,7 +730,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str } output.push_back(INDENT1 "public "); - output.push_back(itype.is_singleton ? "static class " : "class "); + bool is_abstract = !ClassDB::can_instance(itype.name) && ClassDB::is_class_enabled(itype.name); // can_instance returns true if there's a constructor and the class is not 'disabled' + output.push_back(itype.is_singleton ? "static class " : (is_abstract ? "abstract class " : "class ")); output.push_back(itype.proxy_name); if (itype.is_singleton) { @@ -882,7 +899,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str output.push_back("\";\n"); output.push_back(INDENT2 "internal static IntPtr " BINDINGS_PTR_FIELD " = "); - output.push_back(itype.api_type == ClassDB::API_EDITOR ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS); + output.push_back(itype.api_type == ClassDB::API_EDITOR ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS); output.push_back("." ICALL_PREFIX); output.push_back(itype.name); output.push_back(SINGLETON_ICALL_SUFFIX "();\n"); @@ -912,7 +929,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str // The engine will initialize the pointer field of the managed side before calling the constructor // This is why we only allocate a new native object from the constructor if the pointer field is not set output.push_back(")\n" OPEN_BLOCK_L2 "if (" BINDINGS_PTR_FIELD " == IntPtr.Zero)\n" INDENT4 BINDINGS_PTR_FIELD " = "); - output.push_back(itype.api_type == ClassDB::API_EDITOR ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS); + output.push_back(itype.api_type == ClassDB::API_EDITOR ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS); output.push_back("." + ctor_method); output.push_back("(this);\n" CLOSE_BLOCK_L2); } else { @@ -956,7 +973,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str "if (disposed) return;\n" INDENT3 "if (" BINDINGS_PTR_FIELD " != IntPtr.Zero)\n" OPEN_BLOCK_L3 "if (" CS_FIELD_MEMORYOWN ")\n" OPEN_BLOCK_L4 CS_FIELD_MEMORYOWN - " = false;\n" INDENT5 CS_CLASS_NATIVECALLS "." ICALL_OBJECT_DTOR + " = false;\n" INDENT5 BINDINGS_CLASS_NATIVECALLS "." ICALL_OBJECT_DTOR "(this, " BINDINGS_PTR_FIELD ");\n" CLOSE_BLOCK_L4 CLOSE_BLOCK_L3 INDENT3 "this." BINDINGS_PTR_FIELD " = IntPtr.Zero;\n" INDENT3 "GC.SuppressFinalize(this);\n" INDENT3 "disposed = true;\n" CLOSE_BLOCK_L2); @@ -1229,7 +1246,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf { if (p_itype.is_object_type && !p_imethod.is_virtual && !p_imethod.requires_object_call) { p_output.push_back(MEMBER_BEGIN "private static IntPtr "); - p_output.push_back(method_bind_field + " = " CS_CLASS_NATIVECALLS "." ICALL_GET_METHODBIND "(" BINDINGS_NATIVE_NAME_FIELD ", \""); + p_output.push_back(method_bind_field + " = " BINDINGS_CLASS_NATIVECALLS "." ICALL_GET_METHODBIND "(" BINDINGS_NATIVE_NAME_FIELD ", \""); p_output.push_back(p_imethod.name); p_output.push_back("\");\n"); } @@ -1310,7 +1327,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf const InternalCall *im_icall = match->value(); - String im_call = im_icall->editor_only ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS; + String im_call = im_icall->editor_only ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS; im_call += "." + im_icall->name + "(" + icall_params + ");\n"; if (p_imethod.arguments.size()) @@ -1400,25 +1417,33 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { } output.push_back("namespace GodotSharpBindings\n" OPEN_BLOCK); + output.push_back("uint64_t get_core_api_hash() { return "); - output.push_back(itos(GDMono::get_singleton()->get_api_core_hash()) + "; }\n"); + output.push_back(String::num_uint64(GDMono::get_singleton()->get_api_core_hash()) + "; }\n"); + output.push_back("#ifdef TOOLS_ENABLED\n" "uint64_t get_editor_api_hash() { return "); - output.push_back(itos(GDMono::get_singleton()->get_api_editor_hash()) + + output.push_back(String::num_uint64(GDMono::get_singleton()->get_api_editor_hash()) + "; }\n#endif // TOOLS_ENABLED\n"); + + output.push_back("uint32_t get_bindings_version() { return "); + output.push_back(String::num_uint64(BINDINGS_GENERATOR_VERSION) + "; }\n"); + output.push_back("uint32_t get_cs_glue_version() { return "); + output.push_back(String::num_uint64(CS_GLUE_VERSION) + "; }\n"); + output.push_back("void register_generated_icalls() " OPEN_BLOCK); output.push_back("\tgodot_register_header_icalls();"); -#define ADD_INTERNAL_CALL_REGISTRATION(m_icall) \ - { \ - output.push_back("\tmono_add_internal_call("); \ - output.push_back("\"" BINDINGS_NAMESPACE "."); \ - output.push_back(m_icall.editor_only ? CS_CLASS_NATIVECALLS_EDITOR : CS_CLASS_NATIVECALLS); \ - output.push_back("::"); \ - output.push_back(m_icall.name); \ - output.push_back("\", (void*)"); \ - output.push_back(m_icall.name); \ - output.push_back(");\n"); \ +#define ADD_INTERNAL_CALL_REGISTRATION(m_icall) \ + { \ + output.push_back("\tmono_add_internal_call("); \ + output.push_back("\"" BINDINGS_NAMESPACE "."); \ + output.push_back(m_icall.editor_only ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS); \ + output.push_back("::"); \ + output.push_back(m_icall.name); \ + output.push_back("\", (void*)"); \ + output.push_back(m_icall.name); \ + output.push_back(");\n"); \ } bool tools_sequence = false; @@ -1486,6 +1511,14 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { return OK; } +uint32_t BindingsGenerator::get_version() { + return BINDINGS_GENERATOR_VERSION; +} + +uint32_t BindingsGenerator::get_cs_glue_version() { + return CS_GLUE_VERSION; +} + Error BindingsGenerator::_save_file(const String &p_path, const List<String> &p_content) { FileAccessRef file = FileAccess::open(p_path, FileAccess::WRITE); @@ -1528,9 +1561,9 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte if (p_imethod.is_vararg) { if (i < p_imethod.arguments.size() - 1) { c_in_statements += sformat(arg_type->c_in.size() ? arg_type->c_in : TypeInterface::DEFAULT_VARARG_C_IN, "Variant", c_param_name); - c_in_statements += "\t" C_LOCAL_PTRCALL_ARGS ".set(0, "; - c_in_statements += sformat("&%s_in", c_param_name); - c_in_statements += ");\n"; + c_in_statements += "\t" C_LOCAL_PTRCALL_ARGS ".set("; + c_in_statements += itos(i); + c_in_statements += sformat(", &%s_in);\n", c_param_name); } } else { if (i > 0) diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index 9b5a9cea88..f6194139af 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -536,6 +536,9 @@ public: Error generate_cs_editor_project(const String &p_output_dir, const String &p_core_dll_path, bool p_verbose_output = true); Error generate_glue(const String &p_output_dir); + static uint32_t get_version(); + static uint32_t get_cs_glue_version(); + void initialize(); _FORCE_INLINE_ static BindingsGenerator *get_singleton() { diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index 6b41b10981..2f2b5768db 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -33,7 +33,6 @@ #include "main/main.h" #include "../godotsharp_dirs.h" -#include "../mono_gd/gd_mono.h" #include "../mono_gd/gd_mono_class.h" #include "../mono_gd/gd_mono_marshal.h" #include "../utils/path_utils.h" @@ -178,13 +177,15 @@ bool GodotSharpBuilds::build_api_sln(const String &p_name, const String &p_api_s return true; } -bool GodotSharpBuilds::copy_api_assembly(const String &p_src_dir, const String &p_dst_dir, const String &p_assembly_name) { +bool GodotSharpBuilds::copy_api_assembly(const String &p_src_dir, const String &p_dst_dir, const String &p_assembly_name, APIAssembly::Type p_api_type) { String assembly_file = p_assembly_name + ".dll"; String assembly_src = p_src_dir.plus_file(assembly_file); String assembly_dst = p_dst_dir.plus_file(assembly_file); - if (!FileAccess::exists(assembly_dst) || FileAccess::get_modified_time(assembly_src) > FileAccess::get_modified_time(assembly_dst)) { + if (!FileAccess::exists(assembly_dst) || + FileAccess::get_modified_time(assembly_src) > FileAccess::get_modified_time(assembly_dst) || + GDMono::get_singleton()->metadata_is_api_assembly_invalidated(p_api_type)) { DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); String xml_file = p_assembly_name + ".xml"; @@ -200,36 +201,49 @@ bool GodotSharpBuilds::copy_api_assembly(const String &p_src_dir, const String & memdelete(da); if (err != OK) { - show_build_error_dialog("Failed to copy " API_ASSEMBLY_NAME ".dll"); + show_build_error_dialog("Failed to copy " + assembly_file); return false; } + + GDMono::get_singleton()->metadata_set_api_assembly_invalidated(p_api_type, false); } return true; } -bool GodotSharpBuilds::make_api_sln(GodotSharpBuilds::APIType p_api_type) { +String GodotSharpBuilds::_api_folder_name(APIAssembly::Type p_api_type) { + + uint64_t api_hash = p_api_type == APIAssembly::API_CORE ? + GDMono::get_singleton()->get_api_core_hash() : + GDMono::get_singleton()->get_api_editor_hash(); + return String::num_uint64(api_hash) + + "_" + String::num_uint64(BindingsGenerator::get_version()) + + "_" + String::num_uint64(BindingsGenerator::get_cs_glue_version()); +} + +bool GodotSharpBuilds::make_api_sln(APIAssembly::Type p_api_type) { - String api_name = p_api_type == API_CORE ? API_ASSEMBLY_NAME : EDITOR_API_ASSEMBLY_NAME; + String api_name = p_api_type == APIAssembly::API_CORE ? API_ASSEMBLY_NAME : EDITOR_API_ASSEMBLY_NAME; String api_build_config = "Release"; EditorProgress pr("mono_build_release_" + api_name, "Building " + api_name + " solution...", 4); pr.step("Generating " + api_name + " solution"); - uint64_t core_hash = GDMono::get_singleton()->get_api_core_hash(); - uint64_t editor_hash = GDMono::get_singleton()->get_api_editor_hash(); - - String core_api_sln_dir = GodotSharpDirs::get_mono_solutions_dir().plus_file(API_ASSEMBLY_NAME "_" + itos(core_hash)); - String editor_api_sln_dir = GodotSharpDirs::get_mono_solutions_dir().plus_file(EDITOR_API_ASSEMBLY_NAME "_" + itos(editor_hash)); + String core_api_sln_dir = GodotSharpDirs::get_mono_solutions_dir() + .plus_file(_api_folder_name(APIAssembly::API_CORE)) + .plus_file(API_ASSEMBLY_NAME); + String editor_api_sln_dir = GodotSharpDirs::get_mono_solutions_dir() + .plus_file(_api_folder_name(APIAssembly::API_EDITOR)) + .plus_file(EDITOR_API_ASSEMBLY_NAME); - String api_sln_dir = p_api_type == API_CORE ? core_api_sln_dir : editor_api_sln_dir; + String api_sln_dir = p_api_type == APIAssembly::API_CORE ? core_api_sln_dir : editor_api_sln_dir; String api_sln_file = api_sln_dir.plus_file(api_name + ".sln"); if (!DirAccess::exists(api_sln_dir) || !FileAccess::exists(api_sln_file)) { String core_api_assembly; - if (p_api_type == API_EDITOR) { + if (p_api_type == APIAssembly::API_EDITOR) { core_api_assembly = core_api_sln_dir.plus_file("bin") .plus_file(api_build_config) .plus_file(API_ASSEMBLY_NAME ".dll"); @@ -242,7 +256,7 @@ bool GodotSharpBuilds::make_api_sln(GodotSharpBuilds::APIType p_api_type) { BindingsGenerator *gen = BindingsGenerator::get_singleton(); bool gen_verbose = OS::get_singleton()->is_stdout_verbose(); - Error err = p_api_type == API_CORE ? + Error err = p_api_type == APIAssembly::API_CORE ? gen->generate_cs_core_project(api_sln_dir, gen_verbose) : gen->generate_cs_editor_project(api_sln_dir, core_api_assembly, gen_verbose); @@ -275,7 +289,7 @@ bool GodotSharpBuilds::make_api_sln(GodotSharpBuilds::APIType p_api_type) { // Copy the built assembly to the assemblies directory String api_assembly_dir = api_sln_dir.plus_file("bin").plus_file(api_build_config); - if (!GodotSharpBuilds::copy_api_assembly(api_assembly_dir, res_assemblies_dir, api_name)) + if (!GodotSharpBuilds::copy_api_assembly(api_assembly_dir, res_assemblies_dir, api_name, p_api_type)) return false; pr.step("Done"); @@ -283,22 +297,22 @@ bool GodotSharpBuilds::make_api_sln(GodotSharpBuilds::APIType p_api_type) { return true; } -bool GodotSharpBuilds::build_project_blocking() { +bool GodotSharpBuilds::build_project_blocking(const String &p_config) { if (!FileAccess::exists(GodotSharpDirs::get_project_sln_path())) return true; // No solution to build - if (!GodotSharpBuilds::make_api_sln(GodotSharpBuilds::API_CORE)) + if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_CORE)) return false; - if (!GodotSharpBuilds::make_api_sln(GodotSharpBuilds::API_EDITOR)) + if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_EDITOR)) return false; EditorProgress pr("mono_project_debug_build", "Building project solution...", 2); pr.step("Building project solution"); - MonoBuildInfo build_info(GodotSharpDirs::get_project_sln_path(), "Tools"); + MonoBuildInfo build_info(GodotSharpDirs::get_project_sln_path(), p_config); if (!GodotSharpBuilds::get_singleton()->build(build_info)) { GodotSharpBuilds::show_build_error_dialog("Failed to build project solution"); return false; @@ -309,6 +323,11 @@ bool GodotSharpBuilds::build_project_blocking() { return true; } +bool GodotSharpBuilds::editor_build_callback() { + + return build_project_blocking("Tools"); +} + GodotSharpBuilds *GodotSharpBuilds::singleton = NULL; void GodotSharpBuilds::build_exit_callback(const MonoBuildInfo &p_build_info, int p_exit_code) { @@ -362,7 +381,7 @@ GodotSharpBuilds::GodotSharpBuilds() { singleton = this; - EditorNode::get_singleton()->add_build_callback(&GodotSharpBuilds::build_project_blocking); + EditorNode::get_singleton()->add_build_callback(&GodotSharpBuilds::editor_build_callback); // Build tool settings EditorSettings *ed_settings = EditorSettings::get_singleton(); @@ -462,6 +481,7 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) { if (ex) { exited = true; + GDMonoUtils::print_unhandled_exception(ex); String message = "The build constructor threw an exception.\n" + GDMonoUtils::get_exception_name_and_message(ex); build_tab->on_build_exec_failed(message); ERR_EXPLAIN(message); @@ -482,6 +502,7 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) { if (ex) { exited = true; + GDMonoUtils::print_unhandled_exception(ex); String message = "The build method threw an exception.\n" + GDMonoUtils::get_exception_name_and_message(ex); build_tab->on_build_exec_failed(message); ERR_EXPLAIN(message); @@ -504,11 +525,10 @@ void GodotSharpBuilds::BuildProcess::start(bool p_blocking) { } } -GodotSharpBuilds::BuildProcess::BuildProcess(const MonoBuildInfo &p_build_info, GodotSharpBuild_ExitCallback p_callback) { - - build_info = p_build_info; - build_tab = NULL; - exit_callback = p_callback; - exited = true; - exit_code = -1; +GodotSharpBuilds::BuildProcess::BuildProcess(const MonoBuildInfo &p_build_info, GodotSharpBuild_ExitCallback p_callback) : + build_info(p_build_info), + build_tab(NULL), + exit_callback(p_callback), + exited(true), + exit_code(-1) { } diff --git a/modules/mono/editor/godotsharp_builds.h b/modules/mono/editor/godotsharp_builds.h index 5d2390ecd9..27b771e324 100644 --- a/modules/mono/editor/godotsharp_builds.h +++ b/modules/mono/editor/godotsharp_builds.h @@ -31,6 +31,7 @@ #ifndef GODOTSHARP_BUILDS_H #define GODOTSHARP_BUILDS_H +#include "../mono_gd/gd_mono.h" #include "mono_bottom_panel.h" #include "mono_build_info.h" @@ -56,17 +57,14 @@ private: HashMap<MonoBuildInfo, BuildProcess, MonoBuildInfo::Hasher> builds; + static String _api_folder_name(APIAssembly::Type p_api_type); + static GodotSharpBuilds *singleton; friend class GDMono; static void _register_internal_calls(); public: - enum APIType { - API_CORE, - API_EDITOR - }; - enum BuildTool { MSBUILD_MONO, #ifdef WINDOWS_ENABLED @@ -89,11 +87,13 @@ public: bool build_async(const MonoBuildInfo &p_build_info, GodotSharpBuild_ExitCallback p_callback = NULL); static bool build_api_sln(const String &p_name, const String &p_api_sln_dir, const String &p_config); - static bool copy_api_assembly(const String &p_src_dir, const String &p_dst_dir, const String &p_assembly_name); + static bool copy_api_assembly(const String &p_src_dir, const String &p_dst_dir, const String &p_assembly_name, APIAssembly::Type p_api_type); + + static bool make_api_sln(APIAssembly::Type p_api_type); - static bool make_api_sln(APIType p_api_type); + static bool build_project_blocking(const String &p_config); - static bool build_project_blocking(); + static bool editor_build_callback(); GodotSharpBuilds(); ~GodotSharpBuilds(); diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp index 0ef3adfdd0..998da8bda3 100644 --- a/modules/mono/editor/godotsharp_editor.cpp +++ b/modules/mono/editor/godotsharp_editor.cpp @@ -41,6 +41,7 @@ #include "../utils/path_utils.h" #include "bindings_generator.h" #include "csharp_project.h" +#include "godotsharp_export.h" #include "net_solution.h" #ifdef WINDOWS_ENABLED @@ -84,10 +85,10 @@ bool GodotSharpEditor::_create_project_solution() { return false; } - if (!GodotSharpBuilds::make_api_sln(GodotSharpBuilds::API_CORE)) + if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_CORE)) return false; - if (!GodotSharpBuilds::make_api_sln(GodotSharpBuilds::API_EDITOR)) + if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_EDITOR)) return false; pr.step(TTR("Done")); @@ -278,10 +279,11 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) { String about_text = String("C# support in Godot Engine is a brand new feature and a work in progress.\n") + "It is at the alpha stage and thus not suitable for use in production.\n\n" + - "As of Godot 3.0, C# support is not feature-complete and can crash in some situations. " + - "Bugs and usability issues will be addressed gradually over 3.0.x and 3.x releases.\n" + + "As of Godot 3.0, C# support is not feature-complete and may crash in some situations. " + + "Bugs and usability issues will be addressed gradually over 3.0.x and 3.x releases, " + + "including compatibility breaking changes as new features are implemented for a better overall C# experience.\n\n" + "The main missing feature is the ability to export games using C# assemblies - you will therefore be able to develop and run games in the editor, " + - "but not to share them as standalone binaries. This feature is of course high on the priority list and should be available in 3.0.1.\n\n" + + "but not to share them as standalone binaries yet. This feature is of course high on the priority list and should be available as soon as possible.\n\n" + "If you experience issues with this Mono build, please report them on Godot's issue tracker with details about your system, Mono version, IDE, etc.:\n\n" + " https://github.com/godotengine/godot/issues\n\n" + "Your critical feedback at this stage will play a great role in shaping the C# support in future releases, so thank you!"; @@ -315,6 +317,11 @@ GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) { EditorSettings *ed_settings = EditorSettings::get_singleton(); EDITOR_DEF("mono/editor/external_editor", EDITOR_NONE); ed_settings->add_property_hint(PropertyInfo(Variant::INT, "mono/editor/external_editor", PROPERTY_HINT_ENUM, "None,MonoDevelop,Visual Studio Code")); + + // Export plugin + Ref<GodotSharpExport> godotsharp_export; + godotsharp_export.instance(); + EditorExport::get_singleton()->add_export_plugin(godotsharp_export); } GodotSharpEditor::~GodotSharpEditor() { diff --git a/modules/mono/editor/godotsharp_editor.h b/modules/mono/editor/godotsharp_editor.h index 81c49aec30..66da814c8b 100644 --- a/modules/mono/editor/godotsharp_editor.h +++ b/modules/mono/editor/godotsharp_editor.h @@ -32,7 +32,6 @@ #define GODOTSHARP_EDITOR_H #include "godotsharp_builds.h" - #include "monodevelop_instance.h" class GodotSharpEditor : public Node { diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp new file mode 100644 index 0000000000..cd09e6516a --- /dev/null +++ b/modules/mono/editor/godotsharp_export.cpp @@ -0,0 +1,166 @@ +/*************************************************************************/ +/* godotsharp_export.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "godotsharp_export.h" + +#include "../csharp_script.h" +#include "../godotsharp_defs.h" +#include "../godotsharp_dirs.h" +#include "godotsharp_builds.h" + +void GodotSharpExport::_export_file(const String &p_path, const String &p_type, const Set<String> &p_features) { + + if (p_type != CSharpLanguage::get_singleton()->get_type()) + return; + + ERR_FAIL_COND(p_path.get_extension() != CSharpLanguage::get_singleton()->get_extension()); + + // TODO what if the source file is not part of the game's C# project + + if (!GLOBAL_GET("mono/export/include_scripts_content")) { + // We don't want to include the source code on exported games + add_file(p_path, Vector<uint8_t>(), false); + skip(); + } +} + +void GodotSharpExport::_export_begin(const Set<String> &p_features, bool p_debug, const String &p_path, int p_flags) { + + // TODO right now there is no way to stop the export process with an error + + ERR_FAIL_COND(!GDMono::get_singleton()->is_runtime_initialized()); + ERR_FAIL_NULL(GDMono::get_singleton()->get_tools_domain()); + + String build_config = p_debug ? "Debug" : "Release"; + + ERR_FAIL_COND(!GodotSharpBuilds::build_project_blocking(build_config)); + + // Add API assemblies + + String core_api_dll_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(API_ASSEMBLY_NAME ".dll"); + ERR_FAIL_COND(!_add_assembly(core_api_dll_path, core_api_dll_path)); + + String editor_api_dll_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); + ERR_FAIL_COND(!_add_assembly(editor_api_dll_path, editor_api_dll_path)); + + // Add project assembly + + String project_dll_name = ProjectSettings::get_singleton()->get("application/config/name"); + if (project_dll_name.empty()) { + project_dll_name = "UnnamedProject"; + } + + String project_dll_src_path = GodotSharpDirs::get_res_temp_assemblies_base_dir().plus_file(build_config).plus_file(project_dll_name + ".dll"); + String project_dll_dst_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(project_dll_name + ".dll"); + ERR_FAIL_COND(!_add_assembly(project_dll_src_path, project_dll_dst_path)); + + // Add dependencies + + MonoDomain *prev_domain = mono_domain_get(); + MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.ProjectExportDomain"); + + ERR_FAIL_COND(!export_domain); + ERR_FAIL_COND(!mono_domain_set(export_domain, false)); + + Map<String, String> dependencies; + dependencies.insert("mscorlib", GDMono::get_singleton()->get_corlib_assembly()->get_path()); + + GDMonoAssembly *scripts_assembly = GDMonoAssembly::load_from(project_dll_name, project_dll_src_path, /* refonly: */ true); + + ERR_EXPLAIN("Cannot load refonly assembly: " + project_dll_name); + ERR_FAIL_COND(!scripts_assembly); + + Error depend_error = _get_assembly_dependencies(scripts_assembly, dependencies); + + GDMono::get_singleton()->finalize_and_unload_domain(export_domain); + mono_domain_set(prev_domain, false); + + ERR_FAIL_COND(depend_error != OK); + + for (Map<String, String>::Element *E = dependencies.front(); E; E = E->next()) { + String depend_src_path = E->value(); + String depend_dst_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(depend_src_path.get_file()); + ERR_FAIL_COND(!_add_assembly(depend_src_path, depend_dst_path)); + } +} + +bool GodotSharpExport::_add_assembly(const String &p_src_path, const String &p_dst_path) { + + FileAccessRef f = FileAccess::open(p_src_path, FileAccess::READ); + ERR_FAIL_COND_V(!f, false); + + Vector<uint8_t> data; + data.resize(f->get_len()); + f->get_buffer(data.ptrw(), data.size()); + + add_file(p_dst_path, data, false); + + return true; +} + +Error GodotSharpExport::_get_assembly_dependencies(GDMonoAssembly *p_assembly, Map<String, String> &r_dependencies) { + + MonoImage *image = p_assembly->get_image(); + + for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) { + MonoAssemblyName *ref_aname = aname_prealloc; + mono_assembly_get_assemblyref(image, i, ref_aname); + String ref_name = mono_assembly_name_get_name(ref_aname); + + if (ref_name == "mscorlib" || r_dependencies.find(ref_name)) + continue; + + GDMonoAssembly *ref_assembly = NULL; + if (!GDMono::get_singleton()->load_assembly(ref_name, ref_aname, &ref_assembly, /* refonly: */ true)) { + ERR_EXPLAIN("Cannot load refonly assembly: " + ref_name); + ERR_FAIL_V(ERR_CANT_RESOLVE); + } + + r_dependencies.insert(ref_name, ref_assembly->get_path()); + + Error err = _get_assembly_dependencies(ref_assembly, r_dependencies); + if (err != OK) + return err; + } + + return OK; +} + +GodotSharpExport::GodotSharpExport() { + // MonoAssemblyName is an incomplete type (internal to mono), so we can't allocate it ourselves. + // There isn't any api to allocate an empty one either, so we need to do it this way. + aname_prealloc = mono_assembly_name_new("whatever"); + mono_assembly_name_free(aname_prealloc); // "it does not frees the object itself, only the name members" (typo included) +} + +GodotSharpExport::~GodotSharpExport() { + if (aname_prealloc) + mono_free(aname_prealloc); +} diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h new file mode 100644 index 0000000000..b38db9660c --- /dev/null +++ b/modules/mono/editor/godotsharp_export.h @@ -0,0 +1,57 @@ +/*************************************************************************/ +/* godotsharp_export.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef GODOTSHARP_EXPORT_H +#define GODOTSHARP_EXPORT_H + +#include <mono/metadata/image.h> + +#include "editor/editor_export.h" + +#include "../mono_gd/gd_mono_header.h" + +class GodotSharpExport : public EditorExportPlugin { + + MonoAssemblyName *aname_prealloc; + + bool _add_assembly(const String &p_src_path, const String &p_dst_path); + + Error _get_assembly_dependencies(GDMonoAssembly *p_assembly, Map<String, String> &r_dependencies); + +protected: + virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features); + virtual void _export_begin(const Set<String> &p_features, bool p_debug, const String &p_path, int p_flags); + +public: + GodotSharpExport(); + ~GodotSharpExport(); +}; + +#endif // GODOTSHARP_EXPORT_H diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp index 20378a0162..f1cf0bcdf5 100644 --- a/modules/mono/editor/mono_bottom_panel.cpp +++ b/modules/mono/editor/mono_bottom_panel.cpp @@ -142,7 +142,7 @@ void MonoBottomPanel::_errors_toggled(bool p_pressed) { void MonoBottomPanel::_build_project_pressed() { - GodotSharpBuilds::get_singleton()->build_project_blocking(); + GodotSharpBuilds::get_singleton()->build_project_blocking("Tools"); MonoReloadNode::get_singleton()->restart_reload_timer(); CSharpLanguage::get_singleton()->reload_assemblies_if_needed(true); @@ -437,21 +437,16 @@ void MonoBuildTab::_bind_methods() { ClassDB::bind_method("_issue_activated", &MonoBuildTab::_issue_activated); } -MonoBuildTab::MonoBuildTab(const MonoBuildInfo &p_build_info, const String &p_logs_dir) { - - build_info = p_build_info; - logs_dir = p_logs_dir; - - build_exited = false; - - issues_list = memnew(ItemList); +MonoBuildTab::MonoBuildTab(const MonoBuildInfo &p_build_info, const String &p_logs_dir) : + build_info(p_build_info), + logs_dir(p_logs_dir), + build_exited(false), + issues_list(memnew(ItemList)), + error_count(0), + warning_count(0), + errors_visible(true), + warnings_visible(true) { issues_list->set_v_size_flags(SIZE_EXPAND_FILL); issues_list->connect("item_activated", this, "_issue_activated"); add_child(issues_list); - - error_count = 0; - warning_count = 0; - - errors_visible = true; - warnings_visible = true; } diff --git a/modules/mono/glue/cs_files/AABB.cs b/modules/mono/glue/cs_files/AABB.cs index e6e12f7ba3..25458c93e1 100644 --- a/modules/mono/glue/cs_files/AABB.cs +++ b/modules/mono/glue/cs_files/AABB.cs @@ -7,6 +7,12 @@ using System; // file: core/variant_call.cpp // commit: 5ad9be4c24e9d7dc5672fdc42cea896622fe5685 +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + namespace Godot { public struct AABB : IEquatable<AABB> @@ -75,7 +81,7 @@ namespace Godot return new AABB(begin, end - begin); } - public float GetArea() + public real_t GetArea() { return size.x * size.y * size.z; } @@ -108,7 +114,7 @@ namespace Godot public Vector3 GetLongestAxis() { Vector3 axis = new Vector3(1f, 0f, 0f); - float max_size = size.x; + real_t max_size = size.x; if (size.y > max_size) { @@ -128,7 +134,7 @@ namespace Godot public Vector3.Axis GetLongestAxisIndex() { Vector3.Axis axis = Vector3.Axis.X; - float max_size = size.x; + real_t max_size = size.x; if (size.y > max_size) { @@ -145,9 +151,9 @@ namespace Godot return axis; } - public float GetLongestAxisSize() + public real_t GetLongestAxisSize() { - float max_size = size.x; + real_t max_size = size.x; if (size.y > max_size) max_size = size.y; @@ -161,7 +167,7 @@ namespace Godot public Vector3 GetShortestAxis() { Vector3 axis = new Vector3(1f, 0f, 0f); - float max_size = size.x; + real_t max_size = size.x; if (size.y < max_size) { @@ -181,7 +187,7 @@ namespace Godot public Vector3.Axis GetShortestAxisIndex() { Vector3.Axis axis = Vector3.Axis.X; - float max_size = size.x; + real_t max_size = size.x; if (size.y < max_size) { @@ -198,9 +204,9 @@ namespace Godot return axis; } - public float GetShortestAxisSize() + public real_t GetShortestAxisSize() { - float max_size = size.x; + real_t max_size = size.x; if (size.y < max_size) max_size = size.y; @@ -222,7 +228,7 @@ namespace Godot (dir.z > 0f) ? -half_extents.z : half_extents.z); } - public AABB Grow(float by) + public AABB Grow(real_t by) { AABB res = this; @@ -354,23 +360,23 @@ namespace Godot public bool IntersectsSegment(Vector3 from, Vector3 to) { - float min = 0f; - float max = 1f; + real_t min = 0f; + real_t max = 1f; for (int i = 0; i < 3; i++) { - float seg_from = from[i]; - float seg_to = to[i]; - float box_begin = position[i]; - float box_end = box_begin + size[i]; - float cmin, cmax; + real_t seg_from = from[i]; + real_t seg_to = to[i]; + real_t box_begin = position[i]; + real_t box_end = box_begin + size[i]; + real_t cmin, cmax; if (seg_from < seg_to) { if (seg_from > box_end || seg_to < box_begin) return false; - float length = seg_to - seg_from; + real_t length = seg_to - seg_from; cmin = seg_from < box_begin ? (box_begin - seg_from) / length : 0f; cmax = seg_to > box_end ? (box_end - seg_from) / length : 1f; } @@ -379,7 +385,7 @@ namespace Godot if (seg_to > box_end || seg_from < box_begin) return false; - float length = seg_to - seg_from; + real_t length = seg_to - seg_from; cmin = seg_from > box_end ? (box_end - seg_from) / length : 0f; cmax = seg_to < box_begin ? (box_begin - seg_from) / length : 1f; } @@ -419,7 +425,8 @@ namespace Godot return new AABB(min, max - min); } - + + // Constructors public AABB(Vector3 position, Vector3 size) { this.position = position; diff --git a/modules/mono/glue/cs_files/Basis.cs b/modules/mono/glue/cs_files/Basis.cs index c6cdc069ef..2e7e5404c4 100644 --- a/modules/mono/glue/cs_files/Basis.cs +++ b/modules/mono/glue/cs_files/Basis.cs @@ -1,6 +1,12 @@ using System; using System.Runtime.InteropServices; +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + namespace Godot { [StructLayout(LayoutKind.Sequential)] @@ -41,9 +47,27 @@ namespace Godot new Basis(0f, -1f, 0f, 0f, 0f, -1f, 1f, 0f, 0f) }; - public Vector3 x; - public Vector3 y; - public Vector3 z; + public Vector3 x + { + get { return GetAxis(0); } + set { SetAxis(0, value); } + } + + public Vector3 y + { + get { return GetAxis(1); } + set { SetAxis(1, value); } + } + + public Vector3 z + { + get { return GetAxis(2); } + set { SetAxis(2, value); } + } + + private Vector3 _x; + private Vector3 _y; + private Vector3 _z; public static Basis Identity { @@ -70,11 +94,11 @@ namespace Godot switch (index) { case 0: - return x; + return _x; case 1: - return y; + return _y; case 2: - return z; + return _z; default: throw new IndexOutOfRangeException(); } @@ -84,13 +108,13 @@ namespace Godot switch (index) { case 0: - x = value; + _x = value; return; case 1: - y = value; + _y = value; return; case 2: - z = value; + _z = value; return; default: throw new IndexOutOfRangeException(); @@ -98,18 +122,18 @@ namespace Godot } } - public float this[int index, int axis] + public real_t this[int index, int axis] { get { switch (index) { case 0: - return x[axis]; + return _x[axis]; case 1: - return y[axis]; + return _y[axis]; case 2: - return z[axis]; + return _z[axis]; default: throw new IndexOutOfRangeException(); } @@ -119,13 +143,13 @@ namespace Godot switch (index) { case 0: - x[axis] = value; + _x[axis] = value; return; case 1: - y[axis] = value; + _y[axis] = value; return; case 2: - z[axis] = value; + _z[axis] = value; return; default: throw new IndexOutOfRangeException(); @@ -143,7 +167,7 @@ namespace Godot ); } - public float Determinant() + public real_t Determinant() { return this[0, 0] * (this[1, 1] * this[2, 2] - this[2, 1] * this[1, 2]) - this[1, 0] * (this[0, 1] * this[2, 2] - this[2, 1] * this[0, 2]) + @@ -155,6 +179,13 @@ namespace Godot return new Vector3(this[0, axis], this[1, axis], this[2, axis]); } + public void SetAxis(int axis, Vector3 value) + { + this[0, axis] = value.x; + this[1, axis] = value.y; + this[2, axis] = value.z; + } + public Vector3 GetEuler() { Basis m = this.Orthonormalized(); @@ -162,7 +193,7 @@ namespace Godot Vector3 euler; euler.z = 0.0f; - float mxy = m.y[2]; + real_t mxy = m[1, 2]; if (mxy < 1.0f) @@ -170,19 +201,19 @@ namespace Godot if (mxy > -1.0f) { euler.x = Mathf.Asin(-mxy); - euler.y = Mathf.Atan2(m.x[2], m.z[2]); - euler.z = Mathf.Atan2(m.y[0], m.y[1]); + euler.y = Mathf.Atan2(m[0, 2], m[2, 2]); + euler.z = Mathf.Atan2(m[1, 0], m[1, 1]); } else { euler.x = Mathf.PI * 0.5f; - euler.y = -Mathf.Atan2(-m.x[1], m.x[0]); + euler.y = -Mathf.Atan2(-m[0, 1], m[0, 0]); } } else { euler.x = -Mathf.PI * 0.5f; - euler.y = -Mathf.Atan2(m.x[1], m.x[0]); + euler.y = -Mathf.Atan2(-m[0, 1], m[0, 0]); } return euler; @@ -196,7 +227,7 @@ namespace Godot { for (int j = 0; j < 3; j++) { - float v = orth[i, j]; + real_t v = orth[i, j]; if (v > 0.5f) v = 1.0f; @@ -222,26 +253,26 @@ namespace Godot { Basis inv = this; - float[] co = new float[3] + real_t[] co = new real_t[3] { inv[1, 1] * inv[2, 2] - inv[1, 2] * inv[2, 1], inv[1, 2] * inv[2, 0] - inv[1, 0] * inv[2, 2], inv[1, 0] * inv[2, 1] - inv[1, 1] * inv[2, 0] }; - float det = inv[0, 0] * co[0] + inv[0, 1] * co[1] + inv[0, 2] * co[2]; + real_t det = inv[0, 0] * co[0] + inv[0, 1] * co[1] + inv[0, 2] * co[2]; if (det == 0) { return new Basis ( - float.NaN, float.NaN, float.NaN, - float.NaN, float.NaN, float.NaN, - float.NaN, float.NaN, float.NaN + real_t.NaN, real_t.NaN, real_t.NaN, + real_t.NaN, real_t.NaN, real_t.NaN, + real_t.NaN, real_t.NaN, real_t.NaN ); } - float s = 1.0f / det; + real_t s = 1.0f / det; inv = new Basis ( @@ -274,7 +305,7 @@ namespace Godot return Basis.CreateFromAxes(xAxis, yAxis, zAxis); } - public Basis Rotated(Vector3 axis, float phi) + public Basis Rotated(Vector3 axis, real_t phi) { return new Basis(axis, phi) * this; } @@ -296,17 +327,17 @@ namespace Godot return m; } - public float Tdotx(Vector3 with) + public real_t Tdotx(Vector3 with) { return this[0, 0] * with[0] + this[1, 0] * with[1] + this[2, 0] * with[2]; } - public float Tdoty(Vector3 with) + public real_t Tdoty(Vector3 with) { return this[0, 1] * with[0] + this[1, 1] * with[1] + this[2, 1] * with[2]; } - public float Tdotz(Vector3 with) + public real_t Tdotz(Vector3 with) { return this[0, 2] * with[0] + this[1, 2] * with[1] + this[2, 2] * with[2]; } @@ -315,7 +346,7 @@ namespace Godot { Basis tr = this; - float temp = this[0, 1]; + real_t temp = this[0, 1]; this[0, 1] = this[1, 0]; this[1, 0] = temp; @@ -351,91 +382,91 @@ namespace Godot } public Quat Quat() { - float trace = x[0] + y[1] + z[2]; + real_t trace = _x[0] + _y[1] + _z[2]; if (trace > 0.0f) { - float s = Mathf.Sqrt(trace + 1.0f) * 2f; - float inv_s = 1f / s; + real_t s = Mathf.Sqrt(trace + 1.0f) * 2f; + real_t inv_s = 1f / s; return new Quat( - (z[1] - y[2]) * inv_s, - (x[2] - z[0]) * inv_s, - (y[0] - x[1]) * inv_s, + (_z[1] - _y[2]) * inv_s, + (_x[2] - _z[0]) * inv_s, + (_y[0] - _x[1]) * inv_s, s * 0.25f ); - } else if (x[0] > y[1] && x[0] > z[2]) { - float s = Mathf.Sqrt(x[0] - y[1] - z[2] + 1.0f) * 2f; - float inv_s = 1f / s; + } else if (_x[0] > _y[1] && _x[0] > _z[2]) { + real_t s = Mathf.Sqrt(_x[0] - _y[1] - _z[2] + 1.0f) * 2f; + real_t inv_s = 1f / s; return new Quat( s * 0.25f, - (x[1] + y[0]) * inv_s, - (x[2] + z[0]) * inv_s, - (z[1] - y[2]) * inv_s + (_x[1] + _y[0]) * inv_s, + (_x[2] + _z[0]) * inv_s, + (_z[1] - _y[2]) * inv_s ); - } else if (y[1] > z[2]) { - float s = Mathf.Sqrt(-x[0] + y[1] - z[2] + 1.0f) * 2f; - float inv_s = 1f / s; + } else if (_y[1] > _z[2]) { + real_t s = Mathf.Sqrt(-_x[0] + _y[1] - _z[2] + 1.0f) * 2f; + real_t inv_s = 1f / s; return new Quat( - (x[1] + y[0]) * inv_s, + (_x[1] + _y[0]) * inv_s, s * 0.25f, - (y[2] + z[1]) * inv_s, - (x[2] - z[0]) * inv_s + (_y[2] + _z[1]) * inv_s, + (_x[2] - _z[0]) * inv_s ); } else { - float s = Mathf.Sqrt(-x[0] - y[1] + z[2] + 1.0f) * 2f; - float inv_s = 1f / s; + real_t s = Mathf.Sqrt(-_x[0] - _y[1] + _z[2] + 1.0f) * 2f; + real_t inv_s = 1f / s; return new Quat( - (x[2] + z[0]) * inv_s, - (y[2] + z[1]) * inv_s, + (_x[2] + _z[0]) * inv_s, + (_y[2] + _z[1]) * inv_s, s * 0.25f, - (y[0] - x[1]) * inv_s + (_y[0] - _x[1]) * inv_s ); } } public Basis(Quat quat) { - float s = 2.0f / quat.LengthSquared(); - - float xs = quat.x * s; - float ys = quat.y * s; - float zs = quat.z * s; - float wx = quat.w * xs; - float wy = quat.w * ys; - float wz = quat.w * zs; - float xx = quat.x * xs; - float xy = quat.x * ys; - float xz = quat.x * zs; - float yy = quat.y * ys; - float yz = quat.y * zs; - float zz = quat.z * zs; - - this.x = new Vector3(1.0f - (yy + zz), xy - wz, xz + wy); - this.y = new Vector3(xy + wz, 1.0f - (xx + zz), yz - wx); - this.z = new Vector3(xz - wy, yz + wx, 1.0f - (xx + yy)); + real_t s = 2.0f / quat.LengthSquared(); + + real_t xs = quat.x * s; + real_t ys = quat.y * s; + real_t zs = quat.z * s; + real_t wx = quat.w * xs; + real_t wy = quat.w * ys; + real_t wz = quat.w * zs; + real_t xx = quat.x * xs; + real_t xy = quat.x * ys; + real_t xz = quat.x * zs; + real_t yy = quat.y * ys; + real_t yz = quat.y * zs; + real_t zz = quat.z * zs; + + this._x = new Vector3(1.0f - (yy + zz), xy - wz, xz + wy); + this._y = new Vector3(xy + wz, 1.0f - (xx + zz), yz - wx); + this._z = new Vector3(xz - wy, yz + wx, 1.0f - (xx + yy)); } - public Basis(Vector3 axis, float phi) + public Basis(Vector3 axis, real_t phi) { Vector3 axis_sq = new Vector3(axis.x * axis.x, axis.y * axis.y, axis.z * axis.z); - float cosine = Mathf.Cos(phi); - float sine = Mathf.Sin(phi); + real_t cosine = Mathf.Cos( (real_t)phi); + real_t sine = Mathf.Sin( (real_t)phi); - this.x = new Vector3 + this._x = new Vector3 ( axis_sq.x + cosine * (1.0f - axis_sq.x), axis.x * axis.y * (1.0f - cosine) - axis.z * sine, axis.z * axis.x * (1.0f - cosine) + axis.y * sine ); - this.y = new Vector3 + this._y = new Vector3 ( axis.x * axis.y * (1.0f - cosine) + axis.z * sine, axis_sq.y + cosine * (1.0f - axis_sq.y), axis.y * axis.z * (1.0f - cosine) - axis.x * sine ); - this.z = new Vector3 + this._z = new Vector3 ( axis.z * axis.x * (1.0f - cosine) - axis.y * sine, axis.y * axis.z * (1.0f - cosine) + axis.x * sine, @@ -445,16 +476,16 @@ namespace Godot public Basis(Vector3 xAxis, Vector3 yAxis, Vector3 zAxis) { - this.x = xAxis; - this.y = yAxis; - this.z = zAxis; + this._x = xAxis; + this._y = yAxis; + this._z = zAxis; } - public Basis(float xx, float xy, float xz, float yx, float yy, float yz, float zx, float zy, float zz) + public Basis(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) { - this.x = new Vector3(xx, yx, zx); - this.y = new Vector3(xy, yy, zy); - this.z = new Vector3(xz, yz, zz); + this._x = new Vector3(xx, xy, xz); + this._y = new Vector3(yx, yy, yz); + this._z = new Vector3(zx, zy, zz); } public static Basis operator *(Basis left, Basis right) @@ -489,21 +520,21 @@ namespace Godot public bool Equals(Basis other) { - return x.Equals(other.x) && y.Equals(other.y) && z.Equals(other.z); + return _x.Equals(other[0]) && _y.Equals(other[1]) && _z.Equals(other[2]); } public override int GetHashCode() { - return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode(); + return _x.GetHashCode() ^ _y.GetHashCode() ^ _z.GetHashCode(); } public override string ToString() { return String.Format("({0}, {1}, {2})", new object[] { - this.x.ToString(), - this.y.ToString(), - this.z.ToString() + this._x.ToString(), + this._y.ToString(), + this._z.ToString() }); } @@ -511,9 +542,9 @@ namespace Godot { return String.Format("({0}, {1}, {2})", new object[] { - this.x.ToString(format), - this.y.ToString(format), - this.z.ToString(format) + this._x.ToString(format), + this._y.ToString(format), + this._z.ToString(format) }); } } diff --git a/modules/mono/glue/cs_files/Color.cs b/modules/mono/glue/cs_files/Color.cs index f9e31e9703..aa42c487c8 100644 --- a/modules/mono/glue/cs_files/Color.cs +++ b/modules/mono/glue/cs_files/Color.cs @@ -45,8 +45,8 @@ namespace Godot { get { - float max = Mathf.Max(r, Mathf.Max(g, b)); - float min = Mathf.Min(r, Mathf.Min(g, b)); + float max = (float) Mathf.Max(r, (float) Mathf.Max(g, b)); + float min = (float) Mathf.Min(r, (float) Mathf.Min(g, b)); float delta = max - min; @@ -79,8 +79,8 @@ namespace Godot { get { - float max = Mathf.Max(r, Mathf.Max(g, b)); - float min = Mathf.Min(r, Mathf.Min(g, b)); + float max = (float) Mathf.Max(r, (float) Mathf.Max(g, b)); + float min = (float) Mathf.Min(r, (float) Mathf.Min(g, b)); float delta = max - min; @@ -96,7 +96,7 @@ namespace Godot { get { - return Mathf.Max(r, Mathf.Max(g, b)); + return (float) Mathf.Max(r, (float) Mathf.Max(g, b)); } set { @@ -316,7 +316,8 @@ namespace Godot return txt; } - + + // Constructors public Color(float r, float g, float b, float a = 1.0f) { this.r = r; @@ -375,7 +376,7 @@ namespace Godot private String _to_hex(float val) { - int v = (int)Mathf.Clamp(val * 255.0f, 0, 255); + int v = (int) Mathf.Clamp(val * 255.0f, 0, 255); string ret = string.Empty; diff --git a/modules/mono/glue/cs_files/GD.cs b/modules/mono/glue/cs_files/GD.cs index b335ef55e4..1ee7e7d21c 100644 --- a/modules/mono/glue/cs_files/GD.cs +++ b/modules/mono/glue/cs_files/GD.cs @@ -1,5 +1,7 @@ using System; +// TODO: Add comments describing what this class does. It is not obvious. + namespace Godot { public static partial class GD diff --git a/modules/mono/glue/cs_files/Mathf.cs b/modules/mono/glue/cs_files/Mathf.cs index 476396e9a3..adbcc855ef 100644 --- a/modules/mono/glue/cs_files/Mathf.cs +++ b/modules/mono/glue/cs_files/Mathf.cs @@ -1,51 +1,63 @@ using System; +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + namespace Godot { public static class Mathf { - public const float PI = 3.14159274f; - public const float Epsilon = 1e-06f; + // Define constants with Decimal precision and cast down to double or float. + public const real_t PI = (real_t) 3.1415926535897932384626433833M; // 3.1415927f and 3.14159265358979 + + #if REAL_T_IS_DOUBLE + public const real_t Epsilon = 1e-14; // Epsilon size should depend on the precision used. + #else + public const real_t Epsilon = 1e-06f; + #endif - private const float Deg2RadConst = 0.0174532924f; - private const float Rad2DegConst = 57.29578f; + private const real_t Deg2RadConst = (real_t) 0.0174532925199432957692369077M; // 0.0174532924f and 0.0174532925199433 + private const real_t Rad2DegConst = (real_t) 57.295779513082320876798154814M; // 57.29578f and 57.2957795130823 - public static float Abs(float s) + public static real_t Abs(real_t s) { return Math.Abs(s); } - public static float Acos(float s) + public static real_t Acos(real_t s) { - return (float)Math.Acos(s); + return (real_t)Math.Acos(s); } - public static float Asin(float s) + public static real_t Asin(real_t s) { - return (float)Math.Asin(s); + return (real_t)Math.Asin(s); } - public static float Atan(float s) + public static real_t Atan(real_t s) { - return (float)Math.Atan(s); + return (real_t)Math.Atan(s); } - public static float Atan2(float x, float y) + public static real_t Atan2(real_t x, real_t y) { - return (float)Math.Atan2(x, y); + return (real_t)Math.Atan2(x, y); } - public static Vector2 Cartesian2Polar(float x, float y) - { - return new Vector2(Sqrt(x * x + y * y), Atan2(y, x)); - } + public static Vector2 Cartesian2Polar(real_t x, real_t y) + { + return new Vector2(Sqrt(x * x + y * y), Atan2(y, x)); + } - public static float Ceil(float s) + public static real_t Ceil(real_t s) { - return (float)Math.Ceiling(s); + return (real_t)Math.Ceiling(s); } - public static float Clamp(float val, float min, float max) + public static real_t Clamp(real_t val, real_t min, real_t max) { if (val < min) { @@ -59,17 +71,17 @@ namespace Godot return val; } - public static float Cos(float s) + public static real_t Cos(real_t s) { - return (float)Math.Cos(s); + return (real_t)Math.Cos(s); } - public static float Cosh(float s) + public static real_t Cosh(real_t s) { - return (float)Math.Cosh(s); + return (real_t)Math.Cosh(s); } - public static int Decimals(float step) + public static int Decimals(real_t step) { return Decimals((decimal)step); } @@ -79,12 +91,12 @@ namespace Godot return BitConverter.GetBytes(decimal.GetBits(step)[3])[2]; } - public static float Deg2Rad(float deg) + public static real_t Deg2Rad(real_t deg) { return deg * Deg2RadConst; } - public static float Ease(float s, float curve) + public static real_t Ease(real_t s, real_t curve) { if (s < 0f) { @@ -117,17 +129,17 @@ namespace Godot return 0f; } - public static float Exp(float s) + public static real_t Exp(real_t s) { - return (float)Math.Exp(s); + return (real_t)Math.Exp(s); } - public static float Floor(float s) + public static real_t Floor(real_t s) { - return (float)Math.Floor(s); + return (real_t)Math.Floor(s); } - public static float Fposmod(float x, float y) + public static real_t Fposmod(real_t x, real_t y) { if (x >= 0f) { @@ -139,14 +151,14 @@ namespace Godot } } - public static float Lerp(float from, float to, float weight) + public static real_t Lerp(real_t from, real_t to, real_t weight) { return from + (to - from) * Clamp(weight, 0f, 1f); } - public static float Log(float s) + public static real_t Log(real_t s) { - return (float)Math.Log(s); + return (real_t)Math.Log(s); } public static int Max(int a, int b) @@ -154,7 +166,7 @@ namespace Godot return (a > b) ? a : b; } - public static float Max(float a, float b) + public static real_t Max(real_t a, real_t b) { return (a > b) ? a : b; } @@ -164,7 +176,7 @@ namespace Godot return (a < b) ? a : b; } - public static float Min(float a, float b) + public static real_t Min(real_t a, real_t b) { return (a < b) ? a : b; } @@ -181,47 +193,52 @@ namespace Godot return val; } - public static Vector2 Polar2Cartesian(float r, float th) - { - return new Vector2(r * Cos(th), r * Sin(th)); - } + public static Vector2 Polar2Cartesian(real_t r, real_t th) + { + return new Vector2(r * Cos(th), r * Sin(th)); + } - public static float Pow(float x, float y) + public static real_t Pow(real_t x, real_t y) { - return (float)Math.Pow(x, y); + return (real_t)Math.Pow(x, y); } - public static float Rad2Deg(float rad) + public static real_t Rad2Deg(real_t rad) { return rad * Rad2DegConst; } - public static float Round(float s) + public static real_t Round(real_t s) { - return (float)Math.Round(s); + return (real_t)Math.Round(s); } - public static float Sign(float s) + public static int RoundToInt(real_t s) + { + return (int)Math.Round(s); + } + + public static real_t Sign(real_t s) { return (s < 0f) ? -1f : 1f; } - public static float Sin(float s) + public static real_t Sin(real_t s) { - return (float)Math.Sin(s); + return (real_t)Math.Sin(s); } - public static float Sinh(float s) + public static real_t Sinh(real_t s) { - return (float)Math.Sinh(s); + return (real_t)Math.Sinh(s); } - public static float Sqrt(float s) + public static real_t Sqrt(real_t s) { - return (float)Math.Sqrt(s); + return (real_t)Math.Sqrt(s); } - public static float Stepify(float s, float step) + public static real_t Stepify(real_t s, real_t step) { if (step != 0f) { @@ -231,14 +248,26 @@ namespace Godot return s; } - public static float Tan(float s) + public static real_t Tan(real_t s) + { + return (real_t)Math.Tan(s); + } + + public static real_t Tanh(real_t s) + { + return (real_t)Math.Tanh(s); + } + + public static int Wrap(int val, int min, int max) { - return (float)Math.Tan(s); + int rng = max - min; + return min + ((((val - min) % rng) + rng) % rng); } - public static float Tanh(float s) + public static real_t Wrap(real_t val, real_t min, real_t max) { - return (float)Math.Tanh(s); + real_t rng = max - min; + return min + (val - min) - (rng * Floor((val - min) / rng)); } } } diff --git a/modules/mono/glue/cs_files/Plane.cs b/modules/mono/glue/cs_files/Plane.cs index b347c0835a..0f74f3b66a 100644 --- a/modules/mono/glue/cs_files/Plane.cs +++ b/modules/mono/glue/cs_files/Plane.cs @@ -1,12 +1,18 @@ using System; +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + namespace Godot { public struct Plane : IEquatable<Plane> { Vector3 normal; - public float x + public real_t x { get { @@ -18,7 +24,7 @@ namespace Godot } } - public float y + public real_t y { get { @@ -30,7 +36,7 @@ namespace Godot } } - public float z + public real_t z { get { @@ -42,7 +48,7 @@ namespace Godot } } - float d; + real_t d; public Vector3 Center { @@ -52,7 +58,7 @@ namespace Godot } } - public float DistanceTo(Vector3 point) + public real_t DistanceTo(Vector3 point) { return normal.Dot(point) - d; } @@ -62,15 +68,15 @@ namespace Godot return normal * d; } - public bool HasPoint(Vector3 point, float epsilon = Mathf.Epsilon) + public bool HasPoint(Vector3 point, real_t epsilon = Mathf.Epsilon) { - float dist = normal.Dot(point) - d; + real_t dist = normal.Dot(point) - d; return Mathf.Abs(dist) <= epsilon; } public Vector3 Intersect3(Plane b, Plane c) { - float denom = normal.Cross(b.normal).Dot(c.normal); + real_t denom = normal.Cross(b.normal).Dot(c.normal); if (Mathf.Abs(denom) <= Mathf.Epsilon) return new Vector3(); @@ -84,12 +90,12 @@ namespace Godot public Vector3 IntersectRay(Vector3 from, Vector3 dir) { - float den = normal.Dot(dir); + real_t den = normal.Dot(dir); if (Mathf.Abs(den) <= Mathf.Epsilon) return new Vector3(); - float dist = (normal.Dot(from) - d) / den; + real_t dist = (normal.Dot(from) - d) / den; // This is a ray, before the emitting pos (from) does not exist if (dist > Mathf.Epsilon) @@ -101,12 +107,12 @@ namespace Godot public Vector3 IntersectSegment(Vector3 begin, Vector3 end) { Vector3 segment = begin - end; - float den = normal.Dot(segment); + real_t den = normal.Dot(segment); if (Mathf.Abs(den) <= Mathf.Epsilon) return new Vector3(); - float dist = (normal.Dot(begin) - d) / den; + real_t dist = (normal.Dot(begin) - d) / den; if (dist < -Mathf.Epsilon || dist > (1.0f + Mathf.Epsilon)) return new Vector3(); @@ -121,7 +127,7 @@ namespace Godot public Plane Normalized() { - float len = normal.Length(); + real_t len = normal.Length(); if (len == 0) return new Plane(0, 0, 0, 0); @@ -133,14 +139,14 @@ namespace Godot { return point - normal * DistanceTo(point); } - - public Plane(float a, float b, float c, float d) + + // Constructors + public Plane(real_t a, real_t b, real_t c, real_t d) { normal = new Vector3(a, b, c); this.d = d; } - - public Plane(Vector3 normal, float d) + public Plane(Vector3 normal, real_t d) { this.normal = normal; this.d = d; diff --git a/modules/mono/glue/cs_files/Quat.cs b/modules/mono/glue/cs_files/Quat.cs index c0ac41c5d7..0cf3e00ddb 100644 --- a/modules/mono/glue/cs_files/Quat.cs +++ b/modules/mono/glue/cs_files/Quat.cs @@ -1,6 +1,12 @@ using System; using System.Runtime.InteropServices; +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + namespace Godot { [StructLayout(LayoutKind.Sequential)] @@ -8,17 +14,17 @@ namespace Godot { private static readonly Quat identity = new Quat(0f, 0f, 0f, 1f); - public float x; - public float y; - public float z; - public float w; + public real_t x; + public real_t y; + public real_t z; + public real_t w; public static Quat Identity { get { return identity; } } - public float this[int index] + public real_t this[int index] { get { @@ -58,15 +64,15 @@ namespace Godot } } - public Quat CubicSlerp(Quat b, Quat preA, Quat postB, float t) + public Quat CubicSlerp(Quat b, Quat preA, Quat postB, real_t t) { - float t2 = (1.0f - t) * t * 2f; + real_t t2 = (1.0f - t) * t * 2f; Quat sp = Slerp(b, t); Quat sq = preA.Slerpni(postB, t); return sp.Slerpni(sq, t2); } - public float Dot(Quat b) + public real_t Dot(Quat b) { return x * b.x + y * b.y + z * b.z + w * b.w; } @@ -76,12 +82,12 @@ namespace Godot return new Quat(-x, -y, -z, w); } - public float Length() + public real_t Length() { return Mathf.Sqrt(LengthSquared()); } - public float LengthSquared() + public real_t LengthSquared() { return Dot(this); } @@ -91,20 +97,27 @@ namespace Godot return this / Length(); } - public void Set(float x, float y, float z, float w) + public void Set(real_t x, real_t y, real_t z, real_t w) { this.x = x; this.y = y; this.z = z; this.w = w; } + public void Set(Quat q) + { + this.x = q.x; + this.y = q.y; + this.z = q.z; + this.w = q.w; + } - public Quat Slerp(Quat b, float t) + public Quat Slerp(Quat b, real_t t) { // Calculate cosine - float cosom = x * b.x + y * b.y + z * b.z + w * b.w; + real_t cosom = x * b.x + y * b.y + z * b.z + w * b.w; - float[] to1 = new float[4]; + real_t[] to1 = new real_t[4]; // Adjust signs if necessary if (cosom < 0.0) @@ -122,13 +135,13 @@ namespace Godot to1[3] = b.w; } - float sinom, scale0, scale1; + real_t sinom, scale0, scale1; // Calculate coefficients if ((1.0 - cosom) > Mathf.Epsilon) { // Standard case (Slerp) - float omega = Mathf.Acos(cosom); + real_t omega = Mathf.Acos(cosom); sinom = Mathf.Sin(omega); scale0 = Mathf.Sin((1.0f - t) * omega) / sinom; scale1 = Mathf.Sin(t * omega) / sinom; @@ -150,19 +163,19 @@ namespace Godot ); } - public Quat Slerpni(Quat b, float t) + public Quat Slerpni(Quat b, real_t t) { - float dot = this.Dot(b); + real_t dot = this.Dot(b); if (Mathf.Abs(dot) > 0.9999f) { return this; } - float theta = Mathf.Acos(dot); - float sinT = 1.0f / Mathf.Sin(theta); - float newFactor = Mathf.Sin(t * theta) * sinT; - float invFactor = Mathf.Sin((1.0f - t) * theta) * sinT; + real_t theta = Mathf.Acos(dot); + real_t sinT = 1.0f / Mathf.Sin(theta); + real_t newFactor = Mathf.Sin(t * theta) * sinT; + real_t invFactor = Mathf.Sin((1.0f - t) * theta) * sinT; return new Quat ( @@ -180,17 +193,26 @@ namespace Godot return new Vector3(q.x, q.y, q.z); } - public Quat(float x, float y, float z, float w) + // Constructors + public Quat(real_t x, real_t y, real_t z, real_t w) { this.x = x; this.y = y; this.z = z; this.w = w; + } + public Quat(Quat q) + { + this.x = q.x; + this.y = q.y; + this.z = q.z; + this.w = q.w; } - - public Quat(Vector3 axis, float angle) + + public Quat(Vector3 axis, real_t angle) { - float d = axis.Length(); + real_t d = axis.Length(); + real_t angle_t = angle; if (d == 0f) { @@ -201,12 +223,12 @@ namespace Godot } else { - float s = Mathf.Sin(angle * 0.5f) / d; + real_t s = Mathf.Sin(angle_t * 0.5f) / d; x = axis.x * s; y = axis.y * s; z = axis.z * s; - w = Mathf.Cos(angle * 0.5f); + w = Mathf.Cos(angle_t * 0.5f); } } @@ -258,17 +280,17 @@ namespace Godot ); } - public static Quat operator *(Quat left, float right) + public static Quat operator *(Quat left, real_t right) { return new Quat(left.x * right, left.y * right, left.z * right, left.w * right); } - public static Quat operator *(float left, Quat right) + public static Quat operator *(real_t left, Quat right) { return new Quat(right.x * left, right.y * left, right.z * left, right.w * left); } - public static Quat operator /(Quat left, float right) + public static Quat operator /(Quat left, real_t right) { return left * (1.0f / right); } diff --git a/modules/mono/glue/cs_files/Rect2.cs b/modules/mono/glue/cs_files/Rect2.cs index e1fbb65da5..decee35f8c 100644 --- a/modules/mono/glue/cs_files/Rect2.cs +++ b/modules/mono/glue/cs_files/Rect2.cs @@ -1,6 +1,12 @@ using System; using System.Runtime.InteropServices; +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + namespace Godot { [StructLayout(LayoutKind.Sequential)] @@ -26,7 +32,7 @@ namespace Godot get { return position + size; } } - public float Area + public real_t Area { get { return GetArea(); } } @@ -80,12 +86,12 @@ namespace Godot return expanded; } - public float GetArea() + public real_t GetArea() { return size.x * size.y; } - public Rect2 Grow(float by) + public Rect2 Grow(real_t by) { Rect2 g = this; @@ -97,7 +103,7 @@ namespace Godot return g; } - public Rect2 GrowIndividual(float left, float top, float right, float bottom) + public Rect2 GrowIndividual(real_t left, real_t top, real_t right, real_t bottom) { Rect2 g = this; @@ -109,7 +115,7 @@ namespace Godot return g; } - public Rect2 GrowMargin(Margin margin, float by) + public Rect2 GrowMargin(Margin margin, real_t by) { Rect2 g = this; @@ -169,14 +175,24 @@ namespace Godot return newRect; } - + + // Constructors public Rect2(Vector2 position, Vector2 size) { this.position = position; this.size = size; } - - public Rect2(float x, float y, float width, float height) + public Rect2(Vector2 position, real_t width, real_t height) + { + this.position = position; + this.size = new Vector2(width, height); + } + public Rect2(real_t x, real_t y, Vector2 size) + { + this.position = new Vector2(x, y); + this.size = size; + } + public Rect2(real_t x, real_t y, real_t width, real_t height) { this.position = new Vector2(x, y); this.size = new Vector2(width, height); diff --git a/modules/mono/glue/cs_files/StringExtensions.cs b/modules/mono/glue/cs_files/StringExtensions.cs index 5c3ceff97d..cbc337ab19 100644 --- a/modules/mono/glue/cs_files/StringExtensions.cs +++ b/modules/mono/glue/cs_files/StringExtensions.cs @@ -287,7 +287,7 @@ namespace Godot if (sep == -1) return @base; - return @base + rs.substr(0, sep); + return @base + rs.Substr(0, sep); } // <summary> @@ -478,7 +478,7 @@ namespace Godot // </summary> public static bool IsValidIpAddress(this string instance) { - string[] ip = instance.split("."); + string[] ip = instance.Split("."); if (ip.Length != 4) return false; @@ -489,7 +489,7 @@ namespace Godot if (!n.IsValidInteger()) return false; - int val = n.to_int(); + int val = n.ToInt(); if (val < 0 || val > 255) return false; } @@ -571,7 +571,7 @@ namespace Godot // <summary> // Do a simple case insensitive expression match, using ? and * wildcards (see [method expr_match]). // </summary> - public static bool matchn(this string instance, string expr) + public static bool Matchn(this string instance, string expr) { return instance.ExprMatch(expr, false); } @@ -830,7 +830,7 @@ namespace Godot // <summary> // Split the string by a divisor string, return an array of the substrings. Example "One,Two,Three" will return ["One","Two","Three"] if split by ",". // </summary> - public static string[] split(this string instance, string divisor, bool allow_empty = true) + public static string[] Split(this string instance, string divisor, bool allow_empty = true) { return instance.Split(new string[] { divisor }, StringSplitOptions.RemoveEmptyEntries); } @@ -838,7 +838,7 @@ namespace Godot // <summary> // Split the string in floats by using a divisor string, return an array of the substrings. Example "1,2.5,3" will return [1,2.5,3] if split by ",". // </summary> - public static float[] split_floats(this string instance, string divisor, bool allow_empty = true) + public static float[] SplitFloats(this string instance, string divisor, bool allow_empty = true) { List<float> ret = new List<float>(); int from = 0; @@ -872,7 +872,7 @@ namespace Godot // <summary> // Return a copy of the string stripped of any non-printable character at the beginning and the end. The optional arguments are used to toggle stripping on the left and right edges respectively. // </summary> - public static string strip_edges(this string instance, bool left = true, bool right = true) + public static string StripEdges(this string instance, bool left = true, bool right = true) { if (left) { @@ -890,7 +890,7 @@ namespace Godot // <summary> // Return part of the string from the position [code]from[/code], with length [code]len[/code]. // </summary> - public static string substr(this string instance, int from, int len) + public static string Substr(this string instance, int from, int len) { return instance.Substring(from, len); } @@ -898,7 +898,7 @@ namespace Godot // <summary> // Convert the String (which is a character array) to PoolByteArray (which is an array of bytes). The conversion is speeded up in comparison to to_utf8() with the assumption that all the characters the String contains are only ASCII characters. // </summary> - public static byte[] to_ascii(this string instance) + public static byte[] ToAscii(this string instance) { return Encoding.ASCII.GetBytes(instance); } @@ -906,7 +906,7 @@ namespace Godot // <summary> // Convert a string, containing a decimal number, into a [code]float[/code]. // </summary> - public static float to_float(this string instance) + public static float ToFloat(this string instance) { return float.Parse(instance); } @@ -914,7 +914,7 @@ namespace Godot // <summary> // Convert a string, containing an integer number, into an [code]int[/code]. // </summary> - public static int to_int(this string instance) + public static int ToInt(this string instance) { return int.Parse(instance); } @@ -922,7 +922,7 @@ namespace Godot // <summary> // Return the string converted to lowercase. // </summary> - public static string to_lower(this string instance) + public static string ToLower(this string instance) { return instance.ToLower(); } @@ -930,7 +930,7 @@ namespace Godot // <summary> // Return the string converted to uppercase. // </summary> - public static string to_upper(this string instance) + public static string ToUpper(this string instance) { return instance.ToUpper(); } @@ -938,7 +938,7 @@ namespace Godot // <summary> // Convert the String (which is an array of characters) to PoolByteArray (which is an array of bytes). The conversion is a bit slower than to_ascii(), but supports all UTF-8 characters. Therefore, you should prefer this function over to_ascii(). // </summary> - public static byte[] to_utf8(this string instance) + public static byte[] ToUtf8(this string instance) { return Encoding.UTF8.GetBytes(instance); } @@ -946,7 +946,7 @@ namespace Godot // <summary> // Return a copy of the string with special characters escaped using the XML standard. // </summary> - public static string xml_escape(this string instance) + public static string XmlEscape(this string instance) { return SecurityElement.Escape(instance); } @@ -954,7 +954,7 @@ namespace Godot // <summary> // Return a copy of the string with escaped characters replaced by their meanings according to the XML standard. // </summary> - public static string xml_unescape(this string instance) + public static string XmlUnescape(this string instance) { return SecurityElement.FromString(instance).Text; } diff --git a/modules/mono/glue/cs_files/Transform.cs b/modules/mono/glue/cs_files/Transform.cs index 5214100d36..ce26c60706 100644 --- a/modules/mono/glue/cs_files/Transform.cs +++ b/modules/mono/glue/cs_files/Transform.cs @@ -1,6 +1,12 @@ using System; using System.Runtime.InteropServices; +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + namespace Godot { [StructLayout(LayoutKind.Sequential)] @@ -24,7 +30,7 @@ namespace Godot public Transform LookingAt(Vector3 target, Vector3 up) { Transform t = this; - t.set_look_at(origin, target, up); + t.SetLookAt(origin, target, up); return t; } @@ -33,7 +39,7 @@ namespace Godot return new Transform(basis.Orthonormalized(), origin); } - public Transform Rotated(Vector3 axis, float phi) + public Transform Rotated(Vector3 axis, real_t phi) { return new Transform(new Basis(axis, phi), new Vector3()) * this; } @@ -43,7 +49,7 @@ namespace Godot return new Transform(basis.Scaled(scale), origin * scale); } - public void set_look_at(Vector3 eye, Vector3 target, Vector3 up) + public void SetLookAt(Vector3 eye, Vector3 target, Vector3 up) { // Make rotation matrix // Z vector @@ -97,7 +103,8 @@ namespace Godot (basis[0, 2] * vInv.x) + (basis[1, 2] * vInv.y) + (basis[2, 2] * vInv.z) ); } - + + // Constructors public Transform(Vector3 xAxis, Vector3 yAxis, Vector3 zAxis, Vector3 origin) { this.basis = Basis.CreateFromAxes(xAxis, yAxis, zAxis); diff --git a/modules/mono/glue/cs_files/Transform2D.cs b/modules/mono/glue/cs_files/Transform2D.cs index fe7c5b5706..836cca129e 100644 --- a/modules/mono/glue/cs_files/Transform2D.cs +++ b/modules/mono/glue/cs_files/Transform2D.cs @@ -1,6 +1,12 @@ using System; using System.Runtime.InteropServices; +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + namespace Godot { [StructLayout(LayoutKind.Sequential)] @@ -27,7 +33,7 @@ namespace Godot get { return o; } } - public float Rotation + public real_t Rotation { get { return Mathf.Atan2(y.x, o.y); } } @@ -73,7 +79,7 @@ namespace Godot } - public float this[int index, int axis] + public real_t this[int index, int axis] { get { @@ -107,7 +113,7 @@ namespace Godot { Transform2D inv = this; - float det = this[0, 0] * this[1, 1] - this[1, 0] * this[0, 1]; + real_t det = this[0, 0] * this[1, 1] - this[1, 0] * this[0, 1]; if (det == 0) { @@ -119,9 +125,9 @@ namespace Godot ); } - float idet = 1.0f / det; + real_t idet = 1.0f / det; - float temp = this[0, 0]; + real_t temp = this[0, 0]; this[0, 0] = this[1, 1]; this[1, 1] = temp; @@ -143,10 +149,10 @@ namespace Godot return new Vector2(x.Dot(v), y.Dot(v)); } - public Transform2D InterpolateWith(Transform2D m, float c) + public Transform2D InterpolateWith(Transform2D m, real_t c) { - float r1 = Rotation; - float r2 = m.Rotation; + real_t r1 = Rotation; + real_t r2 = m.Rotation; Vector2 s1 = Scale; Vector2 s2 = m.Scale; @@ -155,7 +161,7 @@ namespace Godot Vector2 v1 = new Vector2(Mathf.Cos(r1), Mathf.Sin(r1)); Vector2 v2 = new Vector2(Mathf.Cos(r2), Mathf.Sin(r2)); - float dot = v1.Dot(v2); + real_t dot = v1.Dot(v2); // Clamp dot to [-1, 1] dot = (dot < -1.0f) ? -1.0f : ((dot > 1.0f) ? 1.0f : dot); @@ -169,7 +175,7 @@ namespace Godot } else { - float angle = c * Mathf.Acos(dot); + real_t angle = c * Mathf.Acos(dot); Vector2 v3 = (v2 - v1 * dot).Normalized(); v = v1 * Mathf.Cos(angle) + v3 * Mathf.Sin(angle); } @@ -192,7 +198,7 @@ namespace Godot Transform2D inv = this; // Swap - float temp = inv.x.y; + real_t temp = inv.x.y; inv.x.y = inv.y.x; inv.y.x = temp; @@ -218,7 +224,7 @@ namespace Godot return on; } - public Transform2D Rotated(float phi) + public Transform2D Rotated(real_t phi) { return this * new Transform2D(phi, new Vector2()); } @@ -232,12 +238,12 @@ namespace Godot return copy; } - private float Tdotx(Vector2 with) + private real_t Tdotx(Vector2 with) { return this[0, 0] * with[0] + this[1, 0] * with[1]; } - private float Tdoty(Vector2 with) + private real_t Tdoty(Vector2 with) { return this[0, 1] * with[0] + this[1, 1] * with[1]; } @@ -259,24 +265,26 @@ namespace Godot Vector2 vInv = v - o; return new Vector2(x.Dot(vInv), y.Dot(vInv)); } - + + // Constructors public Transform2D(Vector2 xAxis, Vector2 yAxis, Vector2 origin) { this.x = xAxis; this.y = yAxis; this.o = origin; } - public Transform2D(float xx, float xy, float yx, float yy, float ox, float oy) + + public Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy) { this.x = new Vector2(xx, xy); this.y = new Vector2(yx, yy); this.o = new Vector2(ox, oy); } - public Transform2D(float rot, Vector2 pos) + public Transform2D(real_t rot, Vector2 pos) { - float cr = Mathf.Cos(rot); - float sr = Mathf.Sin(rot); + real_t cr = Mathf.Cos( (real_t)rot); + real_t sr = Mathf.Sin( (real_t)rot); x.x = cr; y.y = cr; x.y = -sr; @@ -288,7 +296,7 @@ namespace Godot { left.o = left.Xform(right.o); - float x0, x1, y0, y1; + real_t x0, x1, y0, y1; x0 = left.Tdotx(right.x); x1 = left.Tdoty(right.x); diff --git a/modules/mono/glue/cs_files/VERSION.txt b/modules/mono/glue/cs_files/VERSION.txt new file mode 100755 index 0000000000..0cfbf08886 --- /dev/null +++ b/modules/mono/glue/cs_files/VERSION.txt @@ -0,0 +1 @@ +2 diff --git a/modules/mono/glue/cs_files/Vector2.cs b/modules/mono/glue/cs_files/Vector2.cs index 238775bda2..6fbe374611 100644 --- a/modules/mono/glue/cs_files/Vector2.cs +++ b/modules/mono/glue/cs_files/Vector2.cs @@ -8,15 +8,21 @@ using System.Runtime.InteropServices; // file: core/variant_call.cpp // commit: 5ad9be4c24e9d7dc5672fdc42cea896622fe5685 +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + namespace Godot { [StructLayout(LayoutKind.Sequential)] public struct Vector2 : IEquatable<Vector2> { - public float x; - public float y; + public real_t x; + public real_t y; - public float this[int index] + public real_t this[int index] { get { @@ -48,7 +54,7 @@ namespace Godot internal void Normalize() { - float length = x * x + y * y; + real_t length = x * x + y * y; if (length != 0f) { @@ -58,7 +64,7 @@ namespace Godot } } - private float Cross(Vector2 b) + private real_t Cross(Vector2 b) { return x * b.y - y * b.x; } @@ -68,22 +74,22 @@ namespace Godot return new Vector2(Mathf.Abs(x), Mathf.Abs(y)); } - public float Angle() + public real_t Angle() { return Mathf.Atan2(y, x); } - public float AngleTo(Vector2 to) + public real_t AngleTo(Vector2 to) { return Mathf.Atan2(Cross(to), Dot(to)); } - public float AngleToPoint(Vector2 to) + public real_t AngleToPoint(Vector2 to) { return Mathf.Atan2(x - to.x, y - to.y); } - public float Aspect() + public real_t Aspect() { return x / y; } @@ -93,10 +99,10 @@ namespace Godot return -Reflect(n); } - public Vector2 Clamped(float length) + public Vector2 Clamped(real_t length) { Vector2 v = this; - float l = this.Length(); + real_t l = this.Length(); if (l > 0 && length < l) { @@ -107,15 +113,15 @@ namespace Godot return v; } - public Vector2 CubicInterpolate(Vector2 b, Vector2 preA, Vector2 postB, float t) + public Vector2 CubicInterpolate(Vector2 b, Vector2 preA, Vector2 postB, real_t t) { Vector2 p0 = preA; Vector2 p1 = this; Vector2 p2 = b; Vector2 p3 = postB; - float t2 = t * t; - float t3 = t2 * t; + real_t t2 = t * t; + real_t t3 = t2 * t; return 0.5f * ((p1 * 2.0f) + (-p0 + p2) * t + @@ -123,17 +129,17 @@ namespace Godot (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3); } - public float DistanceSquaredTo(Vector2 to) + public real_t DistanceSquaredTo(Vector2 to) { return (x - to.x) * (x - to.x) + (y - to.y) * (y - to.y); } - public float DistanceTo(Vector2 to) + public real_t DistanceTo(Vector2 to) { return Mathf.Sqrt((x - to.x) * (x - to.x) + (y - to.y) * (y - to.y)); } - public float Dot(Vector2 with) + public real_t Dot(Vector2 with) { return x * with.x + y * with.y; } @@ -148,17 +154,17 @@ namespace Godot return Mathf.Abs(LengthSquared() - 1.0f) < Mathf.Epsilon; } - public float Length() + public real_t Length() { return Mathf.Sqrt(x * x + y * y); } - public float LengthSquared() + public real_t LengthSquared() { return x * x + y * y; } - public Vector2 LinearInterpolate(Vector2 b, float t) + public Vector2 LinearInterpolate(Vector2 b, real_t t) { Vector2 res = this; @@ -180,12 +186,23 @@ namespace Godot return 2.0f * n * Dot(n) - this; } - public Vector2 Rotated(float phi) + public Vector2 Rotated(real_t phi) { - float rads = Angle() + phi; + real_t rads = Angle() + phi; return new Vector2(Mathf.Cos(rads), Mathf.Sin(rads)) * Length(); } + public void Set(real_t x, real_t y) + { + this.x = x; + this.y = y; + } + public void Set(Vector2 v) + { + this.x = v.x; + this.y = v.y; + } + public Vector2 Slide(Vector2 n) { return this - n * Dot(n); @@ -200,12 +217,36 @@ namespace Godot { return new Vector2(y, -x); } - - public Vector2(float x, float y) + + private static readonly Vector2 zero = new Vector2 (0, 0); + private static readonly Vector2 one = new Vector2 (1, 1); + private static readonly Vector2 negOne = new Vector2 (-1, -1); + + private static readonly Vector2 up = new Vector2 (0, 1); + private static readonly Vector2 down = new Vector2 (0, -1); + private static readonly Vector2 right = new Vector2 (1, 0); + private static readonly Vector2 left = new Vector2 (-1, 0); + + public static Vector2 Zero { get { return zero; } } + public static Vector2 One { get { return one; } } + public static Vector2 NegOne { get { return negOne; } } + + public static Vector2 Up { get { return up; } } + public static Vector2 Down { get { return down; } } + public static Vector2 Right { get { return right; } } + public static Vector2 Left { get { return left; } } + + // Constructors + public Vector2(real_t x, real_t y) { this.x = x; this.y = y; } + public Vector2(Vector2 v) + { + this.x = v.x; + this.y = v.y; + } public static Vector2 operator +(Vector2 left, Vector2 right) { @@ -228,14 +269,14 @@ namespace Godot return vec; } - public static Vector2 operator *(Vector2 vec, float scale) + public static Vector2 operator *(Vector2 vec, real_t scale) { vec.x *= scale; vec.y *= scale; return vec; } - public static Vector2 operator *(float scale, Vector2 vec) + public static Vector2 operator *(real_t scale, Vector2 vec) { vec.x *= scale; vec.y *= scale; @@ -249,7 +290,7 @@ namespace Godot return left; } - public static Vector2 operator /(Vector2 vec, float scale) + public static Vector2 operator /(Vector2 vec, real_t scale) { vec.x /= scale; vec.y /= scale; diff --git a/modules/mono/glue/cs_files/Vector3.cs b/modules/mono/glue/cs_files/Vector3.cs index 190caa4b53..285736d7b8 100644 --- a/modules/mono/glue/cs_files/Vector3.cs +++ b/modules/mono/glue/cs_files/Vector3.cs @@ -8,6 +8,12 @@ using System.Runtime.InteropServices; // file: core/variant_call.cpp // commit: 5ad9be4c24e9d7dc5672fdc42cea896622fe5685 +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + namespace Godot { [StructLayout(LayoutKind.Sequential)] @@ -20,11 +26,11 @@ namespace Godot Z } - public float x; - public float y; - public float z; + public real_t x; + public real_t y; + public real_t z; - public float this[int index] + public real_t this[int index] { get { @@ -61,7 +67,7 @@ namespace Godot internal void Normalize() { - float length = this.Length(); + real_t length = this.Length(); if (length == 0f) { @@ -80,7 +86,7 @@ namespace Godot return new Vector3(Mathf.Abs(x), Mathf.Abs(y), Mathf.Abs(z)); } - public float AngleTo(Vector3 to) + public real_t AngleTo(Vector3 to) { return Mathf.Atan2(Cross(to).Length(), Dot(to)); } @@ -105,15 +111,15 @@ namespace Godot ); } - public Vector3 CubicInterpolate(Vector3 b, Vector3 preA, Vector3 postB, float t) + public Vector3 CubicInterpolate(Vector3 b, Vector3 preA, Vector3 postB, real_t t) { Vector3 p0 = preA; Vector3 p1 = this; Vector3 p2 = b; Vector3 p3 = postB; - float t2 = t * t; - float t3 = t2 * t; + real_t t2 = t * t; + real_t t3 = t2 * t; return 0.5f * ( (p1 * 2.0f) + (-p0 + p2) * t + @@ -122,17 +128,17 @@ namespace Godot ); } - public float DistanceSquaredTo(Vector3 b) + public real_t DistanceSquaredTo(Vector3 b) { return (b - this).LengthSquared(); } - public float DistanceTo(Vector3 b) + public real_t DistanceTo(Vector3 b) { return (b - this).Length(); } - public float Dot(Vector3 b) + public real_t Dot(Vector3 b) { return x * b.x + y * b.y + z * b.z; } @@ -152,25 +158,25 @@ namespace Godot return Mathf.Abs(LengthSquared() - 1.0f) < Mathf.Epsilon; } - public float Length() + public real_t Length() { - float x2 = x * x; - float y2 = y * y; - float z2 = z * z; + real_t x2 = x * x; + real_t y2 = y * y; + real_t z2 = z * z; return Mathf.Sqrt(x2 + y2 + z2); } - public float LengthSquared() + public real_t LengthSquared() { - float x2 = x * x; - float y2 = y * y; - float z2 = z * z; + real_t x2 = x * x; + real_t y2 = y * y; + real_t z2 = z * z; return x2 + y2 + z2; } - public Vector3 LinearInterpolate(Vector3 b, float t) + public Vector3 LinearInterpolate(Vector3 b, real_t t) { return new Vector3 ( @@ -215,11 +221,24 @@ namespace Godot return 2.0f * n * Dot(n) - this; } - public Vector3 Rotated(Vector3 axis, float phi) + public Vector3 Rotated(Vector3 axis, real_t phi) { return new Basis(axis, phi).Xform(this); } + public void Set(real_t x, real_t y, real_t z) + { + this.x = x; + this.y = y; + this.z = z; + } + public void Set(Vector3 v) + { + this.x = v.x; + this.y = v.y; + this.z = v.z; + } + public Vector3 Slide(Vector3 n) { return this - n * Dot(n); @@ -243,13 +262,42 @@ namespace Godot 0f, 0f, z ); } - - public Vector3(float x, float y, float z) + + private static readonly Vector3 zero = new Vector3 (0, 0, 0); + private static readonly Vector3 one = new Vector3 (1, 1, 1); + private static readonly Vector3 negOne = new Vector3 (-1, -1, -1); + + private static readonly Vector3 up = new Vector3 (0, 1, 0); + private static readonly Vector3 down = new Vector3 (0, -1, 0); + private static readonly Vector3 right = new Vector3 (1, 0, 0); + private static readonly Vector3 left = new Vector3 (-1, 0, 0); + private static readonly Vector3 forward = new Vector3 (0, 0, -1); + private static readonly Vector3 back = new Vector3 (0, 0, 1); + + public static Vector3 Zero { get { return zero; } } + public static Vector3 One { get { return one; } } + public static Vector3 NegOne { get { return negOne; } } + + public static Vector3 Up { get { return up; } } + public static Vector3 Down { get { return down; } } + public static Vector3 Right { get { return right; } } + public static Vector3 Left { get { return left; } } + public static Vector3 Forward { get { return forward; } } + public static Vector3 Back { get { return back; } } + + // Constructors + public Vector3(real_t x, real_t y, real_t z) { this.x = x; this.y = y; this.z = z; } + public Vector3(Vector3 v) + { + this.x = v.x; + this.y = v.y; + this.z = v.z; + } public static Vector3 operator +(Vector3 left, Vector3 right) { @@ -275,7 +323,7 @@ namespace Godot return vec; } - public static Vector3 operator *(Vector3 vec, float scale) + public static Vector3 operator *(Vector3 vec, real_t scale) { vec.x *= scale; vec.y *= scale; @@ -283,7 +331,7 @@ namespace Godot return vec; } - public static Vector3 operator *(float scale, Vector3 vec) + public static Vector3 operator *(real_t scale, Vector3 vec) { vec.x *= scale; vec.y *= scale; @@ -299,7 +347,7 @@ namespace Godot return left; } - public static Vector3 operator /(Vector3 vec, float scale) + public static Vector3 operator /(Vector3 vec, real_t scale) { vec.x /= scale; vec.y /= scale; diff --git a/modules/mono/godotsharp_defs.h b/modules/mono/godotsharp_defs.h index 4c26c3e6bd..f604464e8f 100644 --- a/modules/mono/godotsharp_defs.h +++ b/modules/mono/godotsharp_defs.h @@ -39,4 +39,7 @@ #define EDITOR_API_ASSEMBLY_NAME "GodotSharpEditor" #define EDITOR_TOOLS_ASSEMBLY_NAME "GodotSharpTools" +#define BINDINGS_CLASS_NATIVECALLS "NativeCalls" +#define BINDINGS_CLASS_NATIVECALLS_EDITOR "EditorNativeCalls" + #endif // GODOTSHARP_DEFS_H diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 39474f8cbc..0646580eaa 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -42,7 +42,10 @@ #include "project_settings.h" #include "../csharp_script.h" +#include "../godotsharp_dirs.h" #include "../utils/path_utils.h" +#include "gd_mono_class.h" +#include "gd_mono_marshal.h" #include "gd_mono_utils.h" #ifdef TOOLS_ENABLED @@ -71,7 +74,31 @@ void gdmono_MonoPrintCallback(const char *string, mono_bool is_stdout) { GDMono *GDMono::singleton = NULL; +namespace { + +void setup_runtime_main_args() { + CharString execpath = OS::get_singleton()->get_executable_path().utf8(); + + List<String> cmdline_args = OS::get_singleton()->get_cmdline_args(); + + List<CharString> cmdline_args_utf8; + Vector<char *> main_args; + main_args.resize(cmdline_args.size() + 1); + + main_args[0] = execpath.ptrw(); + + int i = 1; + for (List<String>::Element *E = cmdline_args.front(); E; E = E->next()) { + CharString &stored = cmdline_args_utf8.push_back(E->get().utf8())->get(); + main_args[i] = stored.ptrw(); + i++; + } + + mono_runtime_set_main_args(main_args.size(), main_args.ptrw()); +} + #ifdef DEBUG_ENABLED + static bool _wait_for_debugger_msecs(uint32_t p_msecs) { do { @@ -93,9 +120,7 @@ static bool _wait_for_debugger_msecs(uint32_t p_msecs) { return mono_is_debugger_attached(); } -#endif -#ifdef DEBUG_ENABLED void gdmono_debug_init() { mono_debug_init(MONO_DEBUG_FORMAT_MONO); @@ -122,8 +147,11 @@ void gdmono_debug_init() { }; mono_jit_parse_options(2, (char **)options); } + #endif +} // namespace + void GDMono::initialize() { ERR_FAIL_NULL(Engine::get_singleton()); @@ -176,6 +204,8 @@ void GDMono::initialize() { GDMonoUtils::set_main_thread(GDMonoUtils::get_current_thread()); + setup_runtime_main_args(); // Required for System.Environment.GetCommandLineArgs + runtime_initialized = true; OS::get_singleton()->print("Mono: Runtime initialized\n"); @@ -208,7 +238,46 @@ void GDMono::initialize() { _register_internal_calls(); // The following assemblies are not required at initialization - _load_all_script_assemblies(); +#ifndef MONO_GLUE_DISABLED + if (_load_api_assemblies()) { + if (!core_api_assembly_out_of_sync && !editor_api_assembly_out_of_sync && GDMonoUtils::mono_cache.godot_api_cache_updated) { + // Everything is fine with the api assemblies, load the project assembly + _load_project_assembly(); + } else { +#ifdef TOOLS_ENABLED + // The assembly was successfuly loaded, but the full api could not be cached. + // This is most likely an outdated assembly loaded because of an invalid version in the metadata, + // so we invalidate the version in the metadata and unload the script domain. + + if (core_api_assembly_out_of_sync) { + ERR_PRINT("The loaded Core API assembly is out of sync"); + metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); + } else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) { + ERR_PRINT("The loaded Core API assembly is in sync, but the cache update failed"); + metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); + } + + if (editor_api_assembly_out_of_sync) { + ERR_PRINT("The loaded Editor API assembly is out of sync"); + metadata_set_api_assembly_invalidated(APIAssembly::API_EDITOR, true); + } + + OS::get_singleton()->print("Mono: Proceeding to unload scripts domain because of invalid API assemblies\n"); + + Error err = _unload_scripts_domain(); + if (err != OK) { + WARN_PRINT("Mono: Failed to unload scripts domain"); + } +#else + ERR_PRINT("The loaded API assembly is invalid"); + CRASH_NOW(); +#endif + } + } +#else + if (OS::get_singleton()->is_stdout_verbose()) + OS::get_singleton()->print("Mono: Glue disabled, ignoring script assemblies\n"); +#endif mono_install_unhandled_exception_hook(gdmono_unhandled_exception_hook, NULL); @@ -219,7 +288,11 @@ void GDMono::initialize() { namespace GodotSharpBindings { uint64_t get_core_api_hash(); +#ifdef TOOLS_ENABLED uint64_t get_editor_api_hash(); +#endif // TOOLS_ENABLED +uint32_t get_bindings_version(); +uint32_t get_cs_glue_version(); void register_generated_icalls(); } // namespace GodotSharpBindings @@ -271,43 +344,84 @@ GDMonoAssembly **GDMono::get_loaded_assembly(const String &p_name) { return assemblies[domain_id].getptr(p_name); } -bool GDMono::_load_assembly(const String &p_name, GDMonoAssembly **r_assembly) { +bool GDMono::load_assembly(const String &p_name, GDMonoAssembly **r_assembly, bool p_refonly) { + + CRASH_COND(!r_assembly); + + MonoAssemblyName *aname = mono_assembly_name_new(p_name.utf8()); + bool result = load_assembly(p_name, aname, r_assembly, p_refonly); + mono_assembly_name_free(aname); + mono_free(aname); + + return result; +} + +bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly) { CRASH_COND(!r_assembly); if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->print((String() + "Mono: Loading assembly " + p_name + "...\n").utf8()); + OS::get_singleton()->print((String() + "Mono: Loading assembly " + p_name + (p_refonly ? " (refonly)" : "") + "...\n").utf8()); MonoImageOpenStatus status = MONO_IMAGE_OK; - MonoAssemblyName *aname = mono_assembly_name_new(p_name.utf8()); - MonoAssembly *assembly = mono_assembly_load_full(aname, NULL, &status, false); - mono_assembly_name_free(aname); + MonoAssembly *assembly = mono_assembly_load_full(p_aname, NULL, &status, p_refonly); if (!assembly) return false; + ERR_FAIL_COND_V(status != MONO_IMAGE_OK, false); + uint32_t domain_id = mono_domain_get_id(mono_domain_get()); GDMonoAssembly **stored_assembly = assemblies[domain_id].getptr(p_name); - ERR_FAIL_COND_V(status != MONO_IMAGE_OK, false); ERR_FAIL_COND_V(stored_assembly == NULL, false); - ERR_FAIL_COND_V((*stored_assembly)->get_assembly() != assembly, false); + *r_assembly = *stored_assembly; if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->print(String("Mono: Assembly " + p_name + " loaded from path: " + (*r_assembly)->get_path() + "\n").utf8()); + OS::get_singleton()->print(String("Mono: Assembly " + p_name + (p_refonly ? " (refonly)" : "") + " loaded from path: " + (*r_assembly)->get_path() + "\n").utf8()); return true; } +APIAssembly::Version APIAssembly::Version::get_from_loaded_assembly(GDMonoAssembly *p_api_assembly, APIAssembly::Type p_api_type) { + APIAssembly::Version api_assembly_version; + + const char *nativecalls_name = p_api_type == APIAssembly::API_CORE ? + BINDINGS_CLASS_NATIVECALLS : + BINDINGS_CLASS_NATIVECALLS_EDITOR; + + GDMonoClass *nativecalls_klass = p_api_assembly->get_class(BINDINGS_NAMESPACE, nativecalls_name); + + if (nativecalls_klass) { + GDMonoField *api_hash_field = nativecalls_klass->get_field("godot_api_hash"); + if (api_hash_field) + api_assembly_version.godot_api_hash = GDMonoMarshal::unbox<uint64_t>(api_hash_field->get_value(NULL)); + + GDMonoField *binds_ver_field = nativecalls_klass->get_field("bindings_version"); + if (binds_ver_field) + api_assembly_version.bindings_version = GDMonoMarshal::unbox<uint32_t>(binds_ver_field->get_value(NULL)); + + GDMonoField *cs_glue_ver_field = nativecalls_klass->get_field("cs_glue_version"); + if (cs_glue_ver_field) + api_assembly_version.cs_glue_version = GDMonoMarshal::unbox<uint32_t>(cs_glue_ver_field->get_value(NULL)); + } + + return api_assembly_version; +} + +String APIAssembly::to_string(APIAssembly::Type p_type) { + return p_type == APIAssembly::API_CORE ? "API_CORE" : "API_EDITOR"; +} + bool GDMono::_load_corlib_assembly() { if (corlib_assembly) return true; - bool success = _load_assembly("mscorlib", &corlib_assembly); + bool success = load_assembly("mscorlib", &corlib_assembly); if (success) GDMonoUtils::update_corlib_cache(); @@ -317,13 +431,25 @@ bool GDMono::_load_corlib_assembly() { bool GDMono::_load_core_api_assembly() { - if (api_assembly) + if (core_api_assembly) return true; - bool success = _load_assembly(API_ASSEMBLY_NAME, &api_assembly); +#ifdef TOOLS_ENABLED + if (metadata_is_api_assembly_invalidated(APIAssembly::API_CORE)) + return false; +#endif - if (success) + bool success = load_assembly(API_ASSEMBLY_NAME, &core_api_assembly); + + if (success) { +#ifndef MONO_GLUE_DISABLED + APIAssembly::Version api_assembly_ver = APIAssembly::Version::get_from_loaded_assembly(core_api_assembly, APIAssembly::API_CORE); + core_api_assembly_out_of_sync = GodotSharpBindings::get_core_api_hash() != api_assembly_ver.godot_api_hash || + GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || + GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; +#endif GDMonoUtils::update_godot_api_cache(); + } return success; } @@ -334,7 +460,23 @@ bool GDMono::_load_editor_api_assembly() { if (editor_api_assembly) return true; - return _load_assembly(EDITOR_API_ASSEMBLY_NAME, &editor_api_assembly); +#ifdef TOOLS_ENABLED + if (metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR)) + return false; +#endif + + bool success = load_assembly(EDITOR_API_ASSEMBLY_NAME, &editor_api_assembly); + + if (success) { +#ifndef MONO_GLUE_DISABLED + APIAssembly::Version api_assembly_ver = APIAssembly::Version::get_from_loaded_assembly(editor_api_assembly, APIAssembly::API_EDITOR); + editor_api_assembly_out_of_sync = GodotSharpBindings::get_editor_api_hash() != api_assembly_ver.godot_api_hash || + GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || + GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; +#endif + } + + return success; } #endif @@ -346,7 +488,7 @@ bool GDMono::_load_editor_tools_assembly() { _GDMONO_SCOPE_DOMAIN_(tools_domain) - return _load_assembly(EDITOR_TOOLS_ASSEMBLY_NAME, &editor_tools_assembly); + return load_assembly(EDITOR_TOOLS_ASSEMBLY_NAME, &editor_tools_assembly); } #endif @@ -360,17 +502,20 @@ bool GDMono::_load_project_assembly() { name = "UnnamedProject"; } - bool success = _load_assembly(name, &project_assembly); + bool success = load_assembly(name, &project_assembly); - if (success) + if (success) { mono_assembly_set_main(project_assembly->get_assembly()); + } else { + if (OS::get_singleton()->is_stdout_verbose()) + OS::get_singleton()->printerr("Mono: Failed to load project assembly\n"); + } return success; } -bool GDMono::_load_all_script_assemblies() { +bool GDMono::_load_api_assemblies() { -#ifndef MONO_GLUE_DISABLED if (!_load_core_api_assembly()) { if (OS::get_singleton()->is_stdout_verbose()) OS::get_singleton()->printerr("Mono: Failed to load Core API assembly\n"); @@ -385,20 +530,72 @@ bool GDMono::_load_all_script_assemblies() { #endif } - if (!_load_project_assembly()) { - if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->printerr("Mono: Failed to load project assembly\n"); - return false; + return true; +} + +#ifdef TOOLS_ENABLED +String GDMono::_get_api_assembly_metadata_path() { + + return GodotSharpDirs::get_res_metadata_dir().plus_file("api_assemblies.cfg"); +} + +void GDMono::metadata_set_api_assembly_invalidated(APIAssembly::Type p_api_type, bool p_invalidated) { + + String section = APIAssembly::to_string(p_api_type); + String path = _get_api_assembly_metadata_path(); + + Ref<ConfigFile> metadata; + metadata.instance(); + metadata->load(path); + + metadata->set_value(section, "invalidated", p_invalidated); + + String assembly_path = GodotSharpDirs::get_res_assemblies_dir() + .plus_file(p_api_type == APIAssembly::API_CORE ? + API_ASSEMBLY_NAME ".dll" : + EDITOR_API_ASSEMBLY_NAME ".dll"); + + ERR_FAIL_COND(!FileAccess::exists(assembly_path)); + + uint64_t modified_time = FileAccess::get_modified_time(assembly_path); + + metadata->set_value(section, "invalidated_asm_modified_time", String::num_uint64(modified_time)); + + String dir = path.get_base_dir(); + if (!DirAccess::exists(dir)) { + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + ERR_FAIL_COND(!da); + Error err = da->make_dir_recursive(ProjectSettings::get_singleton()->globalize_path(dir)); + ERR_FAIL_COND(err != OK); } - return true; -#else - if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->print("Mono: Glue disbled, ignoring script assemblies\n"); + Error save_err = metadata->save(path); + ERR_FAIL_COND(save_err != OK); +} - return true; -#endif +bool GDMono::metadata_is_api_assembly_invalidated(APIAssembly::Type p_api_type) { + + String section = APIAssembly::to_string(p_api_type); + + Ref<ConfigFile> metadata; + metadata.instance(); + metadata->load(_get_api_assembly_metadata_path()); + + String assembly_path = GodotSharpDirs::get_res_assemblies_dir() + .plus_file(p_api_type == APIAssembly::API_CORE ? + API_ASSEMBLY_NAME ".dll" : + EDITOR_API_ASSEMBLY_NAME ".dll"); + + if (!FileAccess::exists(assembly_path)) + return false; + + uint64_t modified_time = FileAccess::get_modified_time(assembly_path); + + uint64_t stored_modified_time = metadata->get_value(section, "invalidated_asm_modified_time", 0); + + return metadata->get_value(section, "invalidated", false) && modified_time <= stored_modified_time; } +#endif Error GDMono::_load_scripts_domain() { @@ -441,12 +638,15 @@ Error GDMono::_unload_scripts_domain() { _domain_assemblies_cleanup(mono_domain_get_id(scripts_domain)); - api_assembly = NULL; + core_api_assembly = NULL; project_assembly = NULL; #ifdef TOOLS_ENABLED editor_api_assembly = NULL; #endif + core_api_assembly_out_of_sync = false; + editor_api_assembly_out_of_sync = false; + MonoDomain *domain = scripts_domain; scripts_domain = NULL; @@ -501,16 +701,80 @@ Error GDMono::reload_scripts_domain() { return err; } - if (!_load_all_script_assemblies()) { - if (OS::get_singleton()->is_stdout_verbose()) - OS::get_singleton()->printerr("Mono: Failed to load script assemblies\n"); +#ifndef MONO_GLUE_DISABLED + if (!_load_api_assemblies()) { return ERR_CANT_OPEN; } + if (!core_api_assembly_out_of_sync && !editor_api_assembly_out_of_sync && GDMonoUtils::mono_cache.godot_api_cache_updated) { + // Everything is fine with the api assemblies, load the project assembly + _load_project_assembly(); + } else { + // The assembly was successfuly loaded, but the full api could not be cached. + // This is most likely an outdated assembly loaded because of an invalid version in the metadata, + // so we invalidate the version in the metadata and unload the script domain. + + if (core_api_assembly_out_of_sync) { + metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); + } else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) { + ERR_PRINT("Core API assembly is in sync, but the cache update failed"); + metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); + } + + if (editor_api_assembly_out_of_sync) { + metadata_set_api_assembly_invalidated(APIAssembly::API_EDITOR, true); + } + + Error err = _unload_scripts_domain(); + if (err != OK) { + WARN_PRINT("Mono: Failed to unload scripts domain"); + } + + return ERR_CANT_RESOLVE; + } + + if (!_load_project_assembly()) + return ERR_CANT_OPEN; +#else + if (OS::get_singleton()->is_stdout_verbose()) + OS::get_singleton()->print("Mono: Glue disabled, ignoring script assemblies\n"); +#endif + return OK; } #endif +Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) { + + CRASH_COND(p_domain == NULL); + + String domain_name = mono_domain_get_friendly_name(p_domain); + + if (OS::get_singleton()->is_stdout_verbose()) { + OS::get_singleton()->print(String("Mono: Unloading domain `" + domain_name + "`...\n").utf8()); + } + + if (mono_domain_get() != root_domain) + mono_domain_set(root_domain, true); + + mono_gc_collect(mono_gc_max_generation()); + mono_domain_finalize(p_domain, 2000); + mono_gc_collect(mono_gc_max_generation()); + + _domain_assemblies_cleanup(mono_domain_get_id(p_domain)); + + MonoObject *ex = NULL; + mono_domain_try_unload(p_domain, &ex); + + if (ex) { + ERR_PRINTS("Exception thrown when unloading domain `" + domain_name + "`:"); + mono_print_unhandled_exception(ex); + return FAILED; + } + + return OK; +} + GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) { MonoImage *image = mono_class_get_image(p_raw_class); @@ -562,8 +826,11 @@ GDMono::GDMono() { tools_domain = NULL; #endif + core_api_assembly_out_of_sync = false; + editor_api_assembly_out_of_sync = false; + corlib_assembly = NULL; - api_assembly = NULL; + core_api_assembly = NULL; project_assembly = NULL; #ifdef TOOLS_ENABLED editor_api_assembly = NULL; diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 67251778c6..5e01152870 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -31,6 +31,8 @@ #ifndef GD_MONO_H #define GD_MONO_H +#include "core/io/config_file.h" + #include "../godotsharp_defs.h" #include "gd_mono_assembly.h" #include "gd_mono_log.h" @@ -39,6 +41,43 @@ #include "../utils/mono_reg_utils.h" #endif +namespace APIAssembly { +enum Type { + API_CORE, + API_EDITOR +}; + +struct Version { + uint64_t godot_api_hash; + uint32_t bindings_version; + uint32_t cs_glue_version; + + bool operator==(const Version &p_other) const { + return godot_api_hash == p_other.godot_api_hash && + bindings_version == p_other.bindings_version && + cs_glue_version == p_other.cs_glue_version; + } + + Version() : + godot_api_hash(0), + bindings_version(0), + cs_glue_version(0) { + } + + Version(uint64_t p_godot_api_hash, + uint32_t p_bindings_version, + uint32_t p_cs_glue_version) : + godot_api_hash(p_godot_api_hash), + bindings_version(p_bindings_version), + cs_glue_version(p_cs_glue_version) { + } + + static Version get_from_loaded_assembly(GDMonoAssembly *p_api_assembly, Type p_api_type); +}; + +String to_string(Type p_type); +} // namespace APIAssembly + #define SCRIPTS_DOMAIN GDMono::get_singleton()->get_scripts_domain() #ifdef TOOLS_ENABLED #define TOOLS_DOMAIN GDMono::get_singleton()->get_tools_domain() @@ -55,8 +94,11 @@ class GDMono { MonoDomain *tools_domain; #endif + bool core_api_assembly_out_of_sync; + bool editor_api_assembly_out_of_sync; + GDMonoAssembly *corlib_assembly; - GDMonoAssembly *api_assembly; + GDMonoAssembly *core_api_assembly; GDMonoAssembly *project_assembly; #ifdef TOOLS_ENABLED GDMonoAssembly *editor_api_assembly; @@ -75,7 +117,11 @@ class GDMono { #endif bool _load_project_assembly(); - bool _load_all_script_assemblies(); + bool _load_api_assemblies(); + +#ifdef TOOLS_ENABLED + String _get_api_assembly_metadata_path(); +#endif void _register_internal_calls(); @@ -94,8 +140,6 @@ class GDMono { void _initialize_and_check_api_hashes(); #endif - bool _load_assembly(const String &p_name, GDMonoAssembly **r_assembly); - GDMonoLog *gdmono_log; #ifdef WINDOWS_ENABLED @@ -113,6 +157,11 @@ public: #endif #endif +#ifdef TOOLS_ENABLED + void metadata_set_api_assembly_invalidated(APIAssembly::Type p_api_type, bool p_invalidated); + bool metadata_is_api_assembly_invalidated(APIAssembly::Type p_api_type); +#endif + static GDMono *get_singleton() { return singleton; } // Do not use these, unless you know what you're doing @@ -128,7 +177,7 @@ public: #endif _FORCE_INLINE_ GDMonoAssembly *get_corlib_assembly() const { return corlib_assembly; } - _FORCE_INLINE_ GDMonoAssembly *get_api_assembly() const { return api_assembly; } + _FORCE_INLINE_ GDMonoAssembly *get_core_api_assembly() const { return core_api_assembly; } _FORCE_INLINE_ GDMonoAssembly *get_project_assembly() const { return project_assembly; } #ifdef TOOLS_ENABLED _FORCE_INLINE_ GDMonoAssembly *get_editor_api_assembly() const { return editor_api_assembly; } @@ -145,6 +194,10 @@ public: Error reload_scripts_domain(); #endif + bool load_assembly(const String &p_name, GDMonoAssembly **r_assembly, bool p_refonly = false); + bool load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly = false); + Error finalize_and_unload_domain(MonoDomain *p_domain); + void initialize(); GDMono(); diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index ef39b8549d..d062d56dcf 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -43,7 +43,23 @@ bool GDMonoAssembly::no_search = false; Vector<String> GDMonoAssembly::search_dirs; -MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_data) { +MonoAssembly *GDMonoAssembly::assembly_search_hook(MonoAssemblyName *aname, void *user_data) { + return GDMonoAssembly::_search_hook(aname, user_data, false); +} + +MonoAssembly *GDMonoAssembly::assembly_refonly_search_hook(MonoAssemblyName *aname, void *user_data) { + return GDMonoAssembly::_search_hook(aname, user_data, true); +} + +MonoAssembly *GDMonoAssembly::assembly_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data) { + return GDMonoAssembly::_preload_hook(aname, assemblies_path, user_data, false); +} + +MonoAssembly *GDMonoAssembly::assembly_refonly_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data) { + return GDMonoAssembly::_preload_hook(aname, assemblies_path, user_data, true); +} + +MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_data, bool refonly) { (void)user_data; // UNUSED @@ -60,7 +76,7 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_d no_search = true; // Avoid the recursion madness String path; - MonoAssembly *res = NULL; + GDMonoAssembly *res = NULL; for (int i = 0; i < search_dirs.size(); i++) { const String &search_dir = search_dirs[i]; @@ -68,44 +84,49 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_d if (has_extension) { path = search_dir.plus_file(name); if (FileAccess::exists(path)) { - res = _load_assembly_from(name.get_basename(), path); - break; + res = _load_assembly_from(name.get_basename(), path, refonly); + if (res != NULL) + break; } } else { path = search_dir.plus_file(name + ".dll"); if (FileAccess::exists(path)) { - res = _load_assembly_from(name, path); - break; + res = _load_assembly_from(name, path, refonly); + if (res != NULL) + break; } path = search_dir.plus_file(name + ".exe"); if (FileAccess::exists(path)) { - res = _load_assembly_from(name, path); - break; + res = _load_assembly_from(name, path, refonly); + if (res != NULL) + break; } } } no_search = false; - return res; + return res ? res->get_assembly() : NULL; } -MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data) { +MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data, bool refonly) { (void)user_data; // UNUSED if (search_dirs.empty()) { -#ifdef TOOLS_DOMAIN search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_dir()); -#endif search_dirs.push_back(GodotSharpDirs::get_res_assemblies_dir()); search_dirs.push_back(OS::get_singleton()->get_resource_dir()); search_dirs.push_back(OS::get_singleton()->get_executable_path().get_base_dir()); +#ifdef GD_MONO_EDITOR_ASSEMBLIES_DIR + search_dirs.push_back(OS::get_singleton()->get_executable_path().get_base_dir().plus_file(_MKSTR(GD_MONO_EDITOR_ASSEMBLIES_DIR)).simplify_path()); +#endif const char *rootdir = mono_assembly_getrootdir(); if (rootdir) { search_dirs.push_back(String(rootdir).plus_file("mono").plus_file("4.5")); + search_dirs.push_back(String(rootdir).plus_file("mono").plus_file("4.5").plus_file("Facades")); } if (assemblies_path) { @@ -121,10 +142,11 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse if (has_extension ? name == "mscorlib.dll" : name == "mscorlib") { GDMonoAssembly **stored_assembly = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); - if (stored_assembly) return (*stored_assembly)->get_assembly(); + if (stored_assembly) + return (*stored_assembly)->get_assembly(); String path; - MonoAssembly *res = NULL; + GDMonoAssembly *res = NULL; for (int i = 0; i < search_dirs.size(); i++) { const String &search_dir = search_dirs[i]; @@ -132,53 +154,57 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse if (has_extension) { path = search_dir.plus_file(name); if (FileAccess::exists(path)) { - res = _load_assembly_from(name.get_basename(), path); - break; + res = _load_assembly_from(name.get_basename(), path, refonly); + if (res != NULL) + break; } } else { path = search_dir.plus_file(name + ".dll"); if (FileAccess::exists(path)) { - res = _load_assembly_from(name, path); - break; + res = _load_assembly_from(name, path, refonly); + if (res != NULL) + break; } } } - if (res) return res; + return res ? res->get_assembly() : NULL; } return NULL; } -MonoAssembly *GDMonoAssembly::_load_assembly_from(const String &p_name, const String &p_path) { +GDMonoAssembly *GDMonoAssembly::_load_assembly_from(const String &p_name, const String &p_path, bool p_refonly) { GDMonoAssembly *assembly = memnew(GDMonoAssembly(p_name, p_path)); - MonoDomain *domain = mono_domain_get(); - - Error err = assembly->load(domain); + Error err = assembly->load(p_refonly); if (err != OK) { memdelete(assembly); ERR_FAIL_V(NULL); } + MonoDomain *domain = mono_domain_get(); GDMono::get_singleton()->add_assembly(domain ? mono_domain_get_id(domain) : 0, assembly); - return assembly->get_assembly(); + return assembly; } void GDMonoAssembly::initialize() { - // TODO refonly as well? - mono_install_assembly_preload_hook(&GDMonoAssembly::_preload_hook, NULL); - mono_install_assembly_search_hook(&GDMonoAssembly::_search_hook, NULL); + mono_install_assembly_search_hook(&assembly_search_hook, NULL); + mono_install_assembly_refonly_search_hook(&assembly_refonly_search_hook, NULL); + mono_install_assembly_preload_hook(&assembly_preload_hook, NULL); + mono_install_assembly_refonly_preload_hook(&assembly_refonly_preload_hook, NULL); } -Error GDMonoAssembly::load(MonoDomain *p_domain) { +Error GDMonoAssembly::load(bool p_refonly) { ERR_FAIL_COND_V(loaded, ERR_FILE_ALREADY_IN_USE); + refonly = p_refonly; + uint64_t last_modified_time = FileAccess::get_modified_time(path); Vector<uint8_t> data = FileAccess::get_file_as_array(path); @@ -186,14 +212,15 @@ Error GDMonoAssembly::load(MonoDomain *p_domain) { String image_filename(path); - MonoImageOpenStatus status; + MonoImageOpenStatus status = MONO_IMAGE_OK; image = mono_image_open_from_data_with_name( (char *)&data[0], data.size(), - true, &status, false, + true, &status, refonly, image_filename.utf8().get_data()); - ERR_FAIL_COND_V(status != MONO_IMAGE_OK || image == NULL, ERR_FILE_CANT_OPEN); + ERR_FAIL_COND_V(status != MONO_IMAGE_OK, ERR_FILE_CANT_OPEN); + ERR_FAIL_NULL_V(image, ERR_FILE_CANT_OPEN); #ifdef DEBUG_ENABLED String pdb_path(path + ".pdb"); @@ -213,15 +240,10 @@ no_pdb: #endif - assembly = mono_assembly_load_from_full(image, image_filename.utf8().get_data(), &status, false); + assembly = mono_assembly_load_from_full(image, image_filename.utf8().get_data(), &status, refonly); ERR_FAIL_COND_V(status != MONO_IMAGE_OK || assembly == NULL, ERR_FILE_CANT_OPEN); - if (p_domain && mono_image_get_entry_point(image)) { - // TODO should this be removed? do we want to call main? what other effects does this have? - mono_jit_exec(p_domain, assembly, 0, NULL); - } - loaded = true; modified_time = last_modified_time; @@ -373,12 +395,26 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) return match; } +GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_path, bool p_refonly) { + + GDMonoAssembly **loaded_asm = GDMono::get_singleton()->get_loaded_assembly(p_name); + if (loaded_asm) + return *loaded_asm; + + no_search = true; + GDMonoAssembly *res = _load_assembly_from(p_name, p_path, p_refonly); + no_search = false; + + return res; +} + GDMonoAssembly::GDMonoAssembly(const String &p_name, const String &p_path) { loaded = false; gdobject_class_cache_updated = false; name = p_name; path = p_path; + refonly = false; modified_time = 0; assembly = NULL; image = NULL; diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h index 8a5fa19626..5cf744a5a2 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.h +++ b/modules/mono/mono_gd/gd_mono_assembly.h @@ -71,6 +71,7 @@ class GDMonoAssembly { MonoAssembly *assembly; MonoImage *image; + bool refonly; bool loaded; String name; @@ -90,19 +91,25 @@ class GDMonoAssembly { static bool no_search; static Vector<String> search_dirs; - static MonoAssembly *_search_hook(MonoAssemblyName *aname, void *user_data); - static MonoAssembly *_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data); + static MonoAssembly *assembly_search_hook(MonoAssemblyName *aname, void *user_data); + static MonoAssembly *assembly_refonly_search_hook(MonoAssemblyName *aname, void *user_data); + static MonoAssembly *assembly_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data); + static MonoAssembly *assembly_refonly_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data); - static MonoAssembly *_load_assembly_from(const String &p_name, const String &p_path); + static MonoAssembly *_search_hook(MonoAssemblyName *aname, void *user_data, bool refonly); + static MonoAssembly *_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data, bool refonly); + + static GDMonoAssembly *_load_assembly_from(const String &p_name, const String &p_path, bool p_refonly); friend class GDMono; static void initialize(); public: - Error load(MonoDomain *p_domain); + Error load(bool p_refonly); Error wrapper_for_image(MonoImage *p_image); void unload(); + _FORCE_INLINE_ bool is_refonly() const { return refonly; } _FORCE_INLINE_ bool is_loaded() const { return loaded; } _FORCE_INLINE_ MonoImage *get_image() const { return image; } _FORCE_INLINE_ MonoAssembly *get_assembly() const { return assembly; } @@ -115,6 +122,8 @@ public: GDMonoClass *get_object_derived_class(const StringName &p_class); + static GDMonoAssembly *load_from(const String &p_name, const String &p_path, bool p_refonly); + GDMonoAssembly(const String &p_name, const String &p_path = String()); ~GDMonoAssembly(); }; diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 8fd437223f..6572408ab5 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -195,9 +195,9 @@ Dictionary mono_object_to_Dictionary(MonoObject *p_dict); // Transform #define MARSHALLED_OUT_Transform(m_in, m_out) real_t m_out[12] = { \ - m_in.basis[0].x, m_in.basis[1].x, m_in.basis[2].x, \ - m_in.basis[0].y, m_in.basis[1].y, m_in.basis[2].y, \ - m_in.basis[0].z, m_in.basis[1].z, m_in.basis[2].z, \ + m_in.basis[0].x, m_in.basis[0].y, m_in.basis[0].z, \ + m_in.basis[1].x, m_in.basis[1].y, m_in.basis[1].z, \ + m_in.basis[2].x, m_in.basis[2].y, m_in.basis[2].z, \ m_in.origin.x, m_in.origin.y, m_in.origin.z \ }; #define MARSHALLED_IN_Transform(m_in, m_out) Transform m_out( \ diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 42e307cf08..db136a1313 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -143,7 +143,7 @@ void MonoCache::cleanup() { godot_api_cache_updated = false; } -#define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class)) +#define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class)) void update_corlib_cache() { @@ -245,7 +245,7 @@ void update_godot_api_cache() { mono_runtime_object_init(task_scheduler); mono_cache.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler); - mono_cache.corlib_cache_updated = true; + mono_cache.godot_api_cache_updated = true; } void clear_cache() { @@ -305,7 +305,7 @@ GDMonoClass *type_get_proxy_class(const StringName &p_type) { if (class_name[0] == '_') class_name = class_name.substr(1, class_name.length()); - GDMonoClass *klass = GDMono::get_singleton()->get_api_assembly()->get_class(BINDINGS_NAMESPACE, class_name); + GDMonoClass *klass = GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, class_name); #ifdef TOOLS_ENABLED if (!klass) { @@ -321,7 +321,7 @@ GDMonoClass *get_class_native_base(GDMonoClass *p_class) { do { const GDMonoAssembly *assembly = klass->get_assembly(); - if (assembly == GDMono::get_singleton()->get_api_assembly()) + if (assembly == GDMono::get_singleton()->get_core_api_assembly()) return klass; #ifdef TOOLS_ENABLED if (assembly == GDMono::get_singleton()->get_editor_api_assembly()) @@ -420,37 +420,56 @@ void print_unhandled_exception(MonoObject *p_exc, bool p_recursion_caution) { if (!ScriptDebugger::get_singleton()) return; - GDMonoClass *st_klass = CACHED_CLASS(System_Diagnostics_StackTrace); - MonoObject *stack_trace = mono_object_new(mono_domain_get(), st_klass->get_mono_ptr()); + ScriptLanguage::StackInfo separator; + separator.file = ""; + separator.func = "--- " + RTR("End of inner exception stack trace") + " ---"; + separator.line = 0; + + Vector<ScriptLanguage::StackInfo> si; + String exc_msg = ""; + + while (p_exc != NULL) { + GDMonoClass *st_klass = CACHED_CLASS(System_Diagnostics_StackTrace); + MonoObject *stack_trace = mono_object_new(mono_domain_get(), st_klass->get_mono_ptr()); - MonoBoolean need_file_info = true; - void *ctor_args[2] = { p_exc, &need_file_info }; + MonoBoolean need_file_info = true; + void *ctor_args[2] = { p_exc, &need_file_info }; - MonoObject *unexpected_exc = NULL; - CACHED_METHOD(System_Diagnostics_StackTrace, ctor_Exception_bool)->invoke_raw(stack_trace, ctor_args, &unexpected_exc); + MonoObject *unexpected_exc = NULL; + CACHED_METHOD(System_Diagnostics_StackTrace, ctor_Exception_bool)->invoke_raw(stack_trace, ctor_args, &unexpected_exc); - if (unexpected_exc != NULL) { - mono_print_unhandled_exception(unexpected_exc); + if (unexpected_exc != NULL) { + mono_print_unhandled_exception(unexpected_exc); - if (p_recursion_caution) { - // Called from CSharpLanguage::get_current_stack_info, - // so printing an error here could result in endless recursion - OS::get_singleton()->printerr("Mono: Method GDMonoUtils::print_unhandled_exception failed"); - return; - } else { - ERR_FAIL(); + if (p_recursion_caution) { + // Called from CSharpLanguage::get_current_stack_info, + // so printing an error here could result in endless recursion + OS::get_singleton()->printerr("Mono: Method GDMonoUtils::print_unhandled_exception failed"); + return; + } else { + ERR_FAIL(); + } } - } - Vector<ScriptLanguage::StackInfo> si; - if (stack_trace != NULL && !p_recursion_caution) - si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace); + Vector<ScriptLanguage::StackInfo> _si; + if (stack_trace != NULL && !p_recursion_caution) { + _si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace); + for (int i = _si.size() - 1; i >= 0; i--) + si.insert(0, _si[i]); + } + + exc_msg += (exc_msg.length() > 0 ? " ---> " : "") + GDMonoUtils::get_exception_name_and_message(p_exc); + + GDMonoProperty *p_prop = GDMono::get_singleton()->get_class(mono_object_get_class(p_exc))->get_property("InnerException"); + p_exc = p_prop != NULL ? p_prop->get_value(p_exc) : NULL; + if (p_exc != NULL) + si.insert(0, separator); + } String file = si.size() ? si[0].file : __FILE__; String func = si.size() ? si[0].func : FUNCTION_STR; int line = si.size() ? si[0].line : __LINE__; String error_msg = "Unhandled exception"; - String exc_msg = GDMonoUtils::get_exception_name_and_message(p_exc); ScriptDebugger::get_singleton()->send_error(func, file, line, error_msg, exc_msg, ERR_HANDLER_ERROR, si); #endif diff --git a/modules/regex/doc_classes/RegEx.xml b/modules/regex/doc_classes/RegEx.xml index 36de04f293..75e8903ff8 100644 --- a/modules/regex/doc_classes/RegEx.xml +++ b/modules/regex/doc_classes/RegEx.xml @@ -1,17 +1,17 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RegEx" inherits="Reference" category="Core" version="3.1-dev"> +<class name="RegEx" inherits="Reference" category="Core" version="3.1"> <brief_description> Class for searching text for patterns using regular expressions. </brief_description> <description> - Regular Expression (or regex) is a compact programming language that can be used to recognise strings that follow a specific pattern, such as URLs, email addresses, complete sentences, etc. For instance, a regex of [code]ab[0-9][/code] would find any string that is [code]ab[/code] followed by any number from [code]0[/code] to [code]9[/code]. For a more in-depth look, you can easily find various tutorials and detailed explainations on the Internet. + Regular Expression (or regex) is a compact programming language that can be used to recognise strings that follow a specific pattern, such as URLs, email addresses, complete sentences, etc. For instance, a regex of [code]ab[0-9][/code] would find any string that is [code]ab[/code] followed by any number from [code]0[/code] to [code]9[/code]. For a more in-depth look, you can easily find various tutorials and detailed explanations on the Internet. To begin, the RegEx object needs to be compiled with the search pattern using [method compile] before it can be used. [codeblock] var regex = RegEx.new() regex.compile("\\w-(\\d+)") [/codeblock] The search pattern must be escaped first for gdscript before it is escaped for the expression. For example, [code]compile("\\d+")[/code] would be read by RegEx as [code]\d+[/code]. Similarly, [code]compile("\"(?:\\\\.|[^\"])*\"")[/code] would be read as [code]"(?:\\.|[^"])*"[/code] - Using [method search] you can find the pattern within the given text. If a pattern is found, [RegExMatch] is returned and you can retrieve details of the results using fuctions such as [method RegExMatch.get_string] and [method RegExMatch.get_start]. + Using [method search] you can find the pattern within the given text. If a pattern is found, [RegExMatch] is returned and you can retrieve details of the results using functions such as [method RegExMatch.get_string] and [method RegExMatch.get_start]. [codeblock] var regex = RegEx.new() regex.compile("\\w-(\\d+)") diff --git a/modules/regex/doc_classes/RegExMatch.xml b/modules/regex/doc_classes/RegExMatch.xml index 550411d3e0..3d070d2786 100644 --- a/modules/regex/doc_classes/RegExMatch.xml +++ b/modules/regex/doc_classes/RegExMatch.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="RegExMatch" inherits="Reference" category="Core" version="3.1-dev"> +<class name="RegExMatch" inherits="Reference" category="Core" version="3.1"> <brief_description> Contains the results of a regex search. </brief_description> diff --git a/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml b/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml index 8d311ae1b8..ac95a7197f 100644 --- a/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml +++ b/modules/stb_vorbis/doc_classes/AudioStreamOGGVorbis.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamOGGVorbis" inherits="AudioStream" category="Core" version="3.1-dev"> +<class name="AudioStreamOGGVorbis" inherits="AudioStream" category="Core" version="3.1"> <brief_description> OGG Vorbis audio stream driver. </brief_description> diff --git a/modules/stb_vorbis/doc_classes/ResourceImporterOGGVorbis.xml b/modules/stb_vorbis/doc_classes/ResourceImporterOGGVorbis.xml index 5872dd35ff..018f4734ec 100644 --- a/modules/stb_vorbis/doc_classes/ResourceImporterOGGVorbis.xml +++ b/modules/stb_vorbis/doc_classes/ResourceImporterOGGVorbis.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourceImporterOGGVorbis" inherits="ResourceImporter" category="Core" version="3.1-dev"> +<class name="ResourceImporterOGGVorbis" inherits="ResourceImporter" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp index 16ebfa2832..c8acdb689a 100644 --- a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp +++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp @@ -100,6 +100,7 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin ogg_stream.instance(); ogg_stream->set_data(data); + ERR_FAIL_COND_V(!ogg_stream->get_data().size(), ERR_FILE_CORRUPT); ogg_stream->set_loop(loop); ogg_stream->set_loop_offset(loop_offset); diff --git a/modules/theora/doc_classes/ResourceImporterTheora.xml b/modules/theora/doc_classes/ResourceImporterTheora.xml index 6d2de4a9ad..5fc40a6eba 100644 --- a/modules/theora/doc_classes/ResourceImporterTheora.xml +++ b/modules/theora/doc_classes/ResourceImporterTheora.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourceImporterTheora" inherits="ResourceImporter" category="Core" version="3.1-dev"> +<class name="ResourceImporterTheora" inherits="ResourceImporter" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/theora/doc_classes/VideoStreamTheora.xml b/modules/theora/doc_classes/VideoStreamTheora.xml index 550844128d..e7c4727332 100644 --- a/modules/theora/doc_classes/VideoStreamTheora.xml +++ b/modules/theora/doc_classes/VideoStreamTheora.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VideoStreamTheora" inherits="VideoStream" category="Core" version="3.1-dev"> +<class name="VideoStreamTheora" inherits="VideoStream" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index 58c6d73ab2..9e6307c0bf 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -261,14 +261,12 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) { /* look for further theora headers */ while (theora_p && (theora_p < 3) && (ret = ogg_stream_packetout(&to, &op))) { if (ret < 0) { - fprintf(stderr, "Error parsing Theora stream headers; " - "corrupt stream?\n"); + fprintf(stderr, "Error parsing Theora stream headers; corrupt stream?\n"); clear(); return; } if (!th_decode_headerin(&ti, &tc, &ts, &op)) { - fprintf(stderr, "Error parsing Theora stream headers; " - "corrupt stream?\n"); + fprintf(stderr, "Error parsing Theora stream headers; corrupt stream?\n"); clear(); return; } @@ -312,9 +310,15 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) { td = th_decode_alloc(&ti, ts); px_fmt = ti.pixel_fmt; switch (ti.pixel_fmt) { - case TH_PF_420: printf(" 4:2:0 video\n"); break; - case TH_PF_422: printf(" 4:2:2 video\n"); break; - case TH_PF_444: printf(" 4:4:4 video\n"); break; + case TH_PF_420: + //printf(" 4:2:0 video\n"); + break; + case TH_PF_422: + //printf(" 4:2:2 video\n"); + break; + case TH_PF_444: + //printf(" 4:4:4 video\n"); + break; case TH_PF_RSVD: default: printf(" video\n (UNKNOWN Chroma sampling!)\n"); @@ -519,7 +523,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) { #else if (file && /*!videobuf_ready && */ no_theora && theora_eos) { #endif - printf("video done, stopping\n"); + //printf("video done, stopping\n"); stop(); return; }; diff --git a/modules/visual_script/doc_classes/VisualScript.xml b/modules/visual_script/doc_classes/VisualScript.xml index 975b294f30..dab186fb57 100644 --- a/modules/visual_script/doc_classes/VisualScript.xml +++ b/modules/visual_script/doc_classes/VisualScript.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScript" inherits="Script" category="Core" version="3.1-dev"> +<class name="VisualScript" inherits="Script" category="Core" version="3.1"> <brief_description> A script implemented in the Visual Script programming environment. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml b/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml index b529589b98..793291eca2 100644 --- a/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml +++ b/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptBasicTypeConstant" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptBasicTypeConstant" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> A Visual Script node representing a constant from the base types. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml index 9c2ec3b849..0929b227d0 100644 --- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml +++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptBuiltinFunc" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptBuiltinFunc" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> A Visual Script node used to call built-in functions. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptClassConstant.xml b/modules/visual_script/doc_classes/VisualScriptClassConstant.xml index dc946cfcbd..2e3a5b33c0 100644 --- a/modules/visual_script/doc_classes/VisualScriptClassConstant.xml +++ b/modules/visual_script/doc_classes/VisualScriptClassConstant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptClassConstant" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptClassConstant" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Gets a constant from a given class. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptComment.xml b/modules/visual_script/doc_classes/VisualScriptComment.xml index 5c20f27ec2..a4a890ea8a 100644 --- a/modules/visual_script/doc_classes/VisualScriptComment.xml +++ b/modules/visual_script/doc_classes/VisualScriptComment.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptComment" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptComment" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> A Visual Script node used to annotate the script. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptCondition.xml b/modules/visual_script/doc_classes/VisualScriptCondition.xml index a3313a43d9..353898c93a 100644 --- a/modules/visual_script/doc_classes/VisualScriptCondition.xml +++ b/modules/visual_script/doc_classes/VisualScriptCondition.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptCondition" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptCondition" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> A Visual Script node which branches the flow. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptConstant.xml b/modules/visual_script/doc_classes/VisualScriptConstant.xml index 274adb5423..ed633c4135 100644 --- a/modules/visual_script/doc_classes/VisualScriptConstant.xml +++ b/modules/visual_script/doc_classes/VisualScriptConstant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptConstant" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptConstant" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Gets a contant's value. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptConstructor.xml b/modules/visual_script/doc_classes/VisualScriptConstructor.xml index 2efe8d9bd6..14c44c6970 100644 --- a/modules/visual_script/doc_classes/VisualScriptConstructor.xml +++ b/modules/visual_script/doc_classes/VisualScriptConstructor.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptConstructor" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptConstructor" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> A Visual Script node which calls a base type constructor. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptCustomNode.xml b/modules/visual_script/doc_classes/VisualScriptCustomNode.xml index 2165c403d4..b8e77a1b0f 100644 --- a/modules/visual_script/doc_classes/VisualScriptCustomNode.xml +++ b/modules/visual_script/doc_classes/VisualScriptCustomNode.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptCustomNode" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptCustomNode" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> A scripted Visual Script node. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptDeconstruct.xml b/modules/visual_script/doc_classes/VisualScriptDeconstruct.xml index f076c70715..d3158df357 100644 --- a/modules/visual_script/doc_classes/VisualScriptDeconstruct.xml +++ b/modules/visual_script/doc_classes/VisualScriptDeconstruct.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptDeconstruct" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptDeconstruct" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> A Visual Script node which deconstructs a base type instance into its parts. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptEditor.xml b/modules/visual_script/doc_classes/VisualScriptEditor.xml index 1c4542336f..fc49cfc07b 100644 --- a/modules/visual_script/doc_classes/VisualScriptEditor.xml +++ b/modules/visual_script/doc_classes/VisualScriptEditor.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptEditor" inherits="Object" category="Core" version="3.1-dev"> +<class name="VisualScriptEditor" inherits="Object" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml b/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml index 7eea609db4..4bb05525bd 100644 --- a/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml +++ b/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptEmitSignal" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptEmitSignal" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Emits a specified signal. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml b/modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml index 26196f278e..93d7ce3516 100644 --- a/modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml +++ b/modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptEngineSingleton" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptEngineSingleton" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> A Visual Script node returning a singleton from [@GlobalScope] </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptExpression.xml b/modules/visual_script/doc_classes/VisualScriptExpression.xml index 0b93c3092c..343e83cb55 100644 --- a/modules/visual_script/doc_classes/VisualScriptExpression.xml +++ b/modules/visual_script/doc_classes/VisualScriptExpression.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptExpression" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptExpression" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptFunction.xml b/modules/visual_script/doc_classes/VisualScriptFunction.xml index 18daa42797..ec8e955cf7 100644 --- a/modules/visual_script/doc_classes/VisualScriptFunction.xml +++ b/modules/visual_script/doc_classes/VisualScriptFunction.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptFunction" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptFunction" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml b/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml index dc025cfb27..f6116cf539 100644 --- a/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml +++ b/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptFunctionCall" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptFunctionCall" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptFunctionState.xml b/modules/visual_script/doc_classes/VisualScriptFunctionState.xml index 05e9a6cb81..c75dd0cdbc 100644 --- a/modules/visual_script/doc_classes/VisualScriptFunctionState.xml +++ b/modules/visual_script/doc_classes/VisualScriptFunctionState.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptFunctionState" inherits="Reference" category="Core" version="3.1-dev"> +<class name="VisualScriptFunctionState" inherits="Reference" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml b/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml index d0db8cbab3..9d43204f02 100644 --- a/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml +++ b/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptGlobalConstant" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptGlobalConstant" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptIndexGet.xml b/modules/visual_script/doc_classes/VisualScriptIndexGet.xml index 983d8882a7..73c1f47e1a 100644 --- a/modules/visual_script/doc_classes/VisualScriptIndexGet.xml +++ b/modules/visual_script/doc_classes/VisualScriptIndexGet.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptIndexGet" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptIndexGet" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptIndexSet.xml b/modules/visual_script/doc_classes/VisualScriptIndexSet.xml index bc876900f3..652c29a9ac 100644 --- a/modules/visual_script/doc_classes/VisualScriptIndexSet.xml +++ b/modules/visual_script/doc_classes/VisualScriptIndexSet.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptIndexSet" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptIndexSet" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptInputAction.xml b/modules/visual_script/doc_classes/VisualScriptInputAction.xml index 4316bf146d..ab4c23012b 100644 --- a/modules/visual_script/doc_classes/VisualScriptInputAction.xml +++ b/modules/visual_script/doc_classes/VisualScriptInputAction.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptInputAction" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptInputAction" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptIterator.xml b/modules/visual_script/doc_classes/VisualScriptIterator.xml index d815476e2c..7090621bd7 100644 --- a/modules/visual_script/doc_classes/VisualScriptIterator.xml +++ b/modules/visual_script/doc_classes/VisualScriptIterator.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptIterator" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptIterator" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Steps through items in a given input. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptLocalVar.xml b/modules/visual_script/doc_classes/VisualScriptLocalVar.xml index 038fd8c9cd..5c8ee6453c 100644 --- a/modules/visual_script/doc_classes/VisualScriptLocalVar.xml +++ b/modules/visual_script/doc_classes/VisualScriptLocalVar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptLocalVar" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptLocalVar" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Gets a local variable's value. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml b/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml index fa65a89c4a..f2e6c48907 100644 --- a/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml +++ b/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptLocalVarSet" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptLocalVarSet" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Changes a local variable's value. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptMathConstant.xml b/modules/visual_script/doc_classes/VisualScriptMathConstant.xml index 243ab03b49..df439f8794 100644 --- a/modules/visual_script/doc_classes/VisualScriptMathConstant.xml +++ b/modules/visual_script/doc_classes/VisualScriptMathConstant.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptMathConstant" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptMathConstant" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Commonly used mathematical constants. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptNode.xml b/modules/visual_script/doc_classes/VisualScriptNode.xml index c2c5464047..941a0cd91a 100644 --- a/modules/visual_script/doc_classes/VisualScriptNode.xml +++ b/modules/visual_script/doc_classes/VisualScriptNode.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptNode" inherits="Resource" category="Core" version="3.1-dev"> +<class name="VisualScriptNode" inherits="Resource" category="Core" version="3.1"> <brief_description> A node which is part of a [VisualScript]. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptOperator.xml b/modules/visual_script/doc_classes/VisualScriptOperator.xml index 68a57191de..e60d50c977 100644 --- a/modules/visual_script/doc_classes/VisualScriptOperator.xml +++ b/modules/visual_script/doc_classes/VisualScriptOperator.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptOperator" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptOperator" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptPreload.xml b/modules/visual_script/doc_classes/VisualScriptPreload.xml index 19abc27053..5a2886ccac 100644 --- a/modules/visual_script/doc_classes/VisualScriptPreload.xml +++ b/modules/visual_script/doc_classes/VisualScriptPreload.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptPreload" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptPreload" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Creates a new [Resource] or loads one from the filesystem. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml index 88aac85f59..60cc8fdd4f 100644 --- a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml +++ b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptPropertyGet" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptPropertyGet" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptPropertySet.xml b/modules/visual_script/doc_classes/VisualScriptPropertySet.xml index ac962a071d..8f29e9d152 100644 --- a/modules/visual_script/doc_classes/VisualScriptPropertySet.xml +++ b/modules/visual_script/doc_classes/VisualScriptPropertySet.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptPropertySet" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptPropertySet" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptResourcePath.xml b/modules/visual_script/doc_classes/VisualScriptResourcePath.xml index a3144582cb..f6300e03f0 100644 --- a/modules/visual_script/doc_classes/VisualScriptResourcePath.xml +++ b/modules/visual_script/doc_classes/VisualScriptResourcePath.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptResourcePath" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptResourcePath" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptReturn.xml b/modules/visual_script/doc_classes/VisualScriptReturn.xml index ca50f811c3..6095520eff 100644 --- a/modules/visual_script/doc_classes/VisualScriptReturn.xml +++ b/modules/visual_script/doc_classes/VisualScriptReturn.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptReturn" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptReturn" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Exits a function and returns an optional value. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptSceneNode.xml b/modules/visual_script/doc_classes/VisualScriptSceneNode.xml index 3d4bdcfd0a..7704eaba04 100644 --- a/modules/visual_script/doc_classes/VisualScriptSceneNode.xml +++ b/modules/visual_script/doc_classes/VisualScriptSceneNode.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSceneNode" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptSceneNode" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Node reference. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptSceneTree.xml b/modules/visual_script/doc_classes/VisualScriptSceneTree.xml index c77b674b64..2c2af9262d 100644 --- a/modules/visual_script/doc_classes/VisualScriptSceneTree.xml +++ b/modules/visual_script/doc_classes/VisualScriptSceneTree.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSceneTree" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptSceneTree" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptSelect.xml b/modules/visual_script/doc_classes/VisualScriptSelect.xml index f1aad841ca..0731fc77e1 100644 --- a/modules/visual_script/doc_classes/VisualScriptSelect.xml +++ b/modules/visual_script/doc_classes/VisualScriptSelect.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSelect" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptSelect" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Chooses between two input values. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptSelf.xml b/modules/visual_script/doc_classes/VisualScriptSelf.xml index c2847fcada..61a73e104c 100644 --- a/modules/visual_script/doc_classes/VisualScriptSelf.xml +++ b/modules/visual_script/doc_classes/VisualScriptSelf.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSelf" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptSelf" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Outputs a reference to the current instance. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptSequence.xml b/modules/visual_script/doc_classes/VisualScriptSequence.xml index 0180f34c72..c71e068045 100644 --- a/modules/visual_script/doc_classes/VisualScriptSequence.xml +++ b/modules/visual_script/doc_classes/VisualScriptSequence.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSequence" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptSequence" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Executes a series of Sequence ports. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptSubCall.xml b/modules/visual_script/doc_classes/VisualScriptSubCall.xml index d34d0b7127..46aeebab9c 100644 --- a/modules/visual_script/doc_classes/VisualScriptSubCall.xml +++ b/modules/visual_script/doc_classes/VisualScriptSubCall.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSubCall" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptSubCall" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptSwitch.xml b/modules/visual_script/doc_classes/VisualScriptSwitch.xml index ea9e6438cf..a00811a29b 100644 --- a/modules/visual_script/doc_classes/VisualScriptSwitch.xml +++ b/modules/visual_script/doc_classes/VisualScriptSwitch.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSwitch" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptSwitch" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Branches program flow based on a given input's value. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptTypeCast.xml b/modules/visual_script/doc_classes/VisualScriptTypeCast.xml index 4bdfeab35b..0bdc4ce89d 100644 --- a/modules/visual_script/doc_classes/VisualScriptTypeCast.xml +++ b/modules/visual_script/doc_classes/VisualScriptTypeCast.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptTypeCast" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptTypeCast" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptVariableGet.xml b/modules/visual_script/doc_classes/VisualScriptVariableGet.xml index 76c218294e..06178a399d 100644 --- a/modules/visual_script/doc_classes/VisualScriptVariableGet.xml +++ b/modules/visual_script/doc_classes/VisualScriptVariableGet.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptVariableGet" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptVariableGet" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Gets a variable's value. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptVariableSet.xml b/modules/visual_script/doc_classes/VisualScriptVariableSet.xml index 0262ad5dfb..5969f25060 100644 --- a/modules/visual_script/doc_classes/VisualScriptVariableSet.xml +++ b/modules/visual_script/doc_classes/VisualScriptVariableSet.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptVariableSet" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptVariableSet" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Changes a variable's value. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptWhile.xml b/modules/visual_script/doc_classes/VisualScriptWhile.xml index 46a6ea7a30..b9e7f6a553 100644 --- a/modules/visual_script/doc_classes/VisualScriptWhile.xml +++ b/modules/visual_script/doc_classes/VisualScriptWhile.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptWhile" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptWhile" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> Conditional loop. </brief_description> diff --git a/modules/visual_script/doc_classes/VisualScriptYield.xml b/modules/visual_script/doc_classes/VisualScriptYield.xml index a1129ffbd7..c4698f746a 100644 --- a/modules/visual_script/doc_classes/VisualScriptYield.xml +++ b/modules/visual_script/doc_classes/VisualScriptYield.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptYield" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptYield" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml b/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml index ad3a016c0d..b67e4ab1b8 100644 --- a/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml +++ b/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptYieldSignal" inherits="VisualScriptNode" category="Core" version="3.1-dev"> +<class name="VisualScriptYieldSignal" inherits="VisualScriptNode" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 5987fdf5da..ef680547ca 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -2182,7 +2182,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o Ref<VisualScriptNode> node = F->get().node; VisualScriptNodeInstance *instance = instances[F->key()]; - // conect to default values + // connect to default values for (int i = 0; i < instance->input_port_count; i++) { if (instance->input_ports[i] == -1) { @@ -2192,7 +2192,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o } } - // conect to trash + // connect to trash for (int i = 0; i < instance->output_port_count; i++) { if (instance->output_ports[i] == -1) { instance->output_ports[i] = function.trash_pos; //trash is same for all diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 69503e631c..eb10c5e99f 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -3236,6 +3236,12 @@ void VisualScriptEditor::_member_option(int p_option) { } } +void VisualScriptEditor::add_syntax_highlighter(SyntaxHighlighter *p_highlighter) { +} + +void VisualScriptEditor::set_syntax_highlighter(SyntaxHighlighter *p_highlighter) { +} + void VisualScriptEditor::_bind_methods() { ClassDB::bind_method("_member_button", &VisualScriptEditor::_member_button); diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index 80bbf142d9..72b5e09222 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -246,6 +246,9 @@ protected: static void _bind_methods(); public: + virtual void add_syntax_highlighter(SyntaxHighlighter *p_highlighter); + virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter); + virtual void apply_code(); virtual Ref<Script> get_edited_script() const; virtual Vector<String> get_functions(); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index e0b4fde237..c5654a5a20 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -425,7 +425,7 @@ PropertyInfo VisualScriptOperator::get_input_value_port_info(int p_idx) const { } PropertyInfo VisualScriptOperator::get_output_value_port_info(int p_idx) const { static const Variant::Type port_types[Variant::OP_MAX] = { - //comparation + //comparison Variant::BOOL, //OP_EQUAL, Variant::BOOL, //OP_NOT_EQUAL, Variant::BOOL, //OP_LESS, @@ -466,7 +466,7 @@ PropertyInfo VisualScriptOperator::get_output_value_port_info(int p_idx) const { } static const char *op_names[] = { - //comparation + //comparison "Equal", //OP_EQUAL, "NotEqual", //OP_NOT_EQUAL, "Less", //OP_LESS, @@ -506,7 +506,7 @@ String VisualScriptOperator::get_caption() const { String VisualScriptOperator::get_text() const { static const wchar_t *op_names[] = { - //comparation + //comparison L"A = B", //OP_EQUAL, L"A \u2260 B", //OP_NOT_EQUAL, L"A < B", //OP_LESS, diff --git a/modules/webm/SCsub b/modules/webm/SCsub index 2f1a28a54c..33561da098 100644 --- a/modules/webm/SCsub +++ b/modules/webm/SCsub @@ -18,6 +18,10 @@ thirdparty_libsimplewebm_sources = [thirdparty_libsimplewebm_dir + file for file env_webm.add_source_files(env.modules_sources, thirdparty_libsimplewebm_sources) env_webm.Append(CPPPATH=[thirdparty_libsimplewebm_dir, thirdparty_libsimplewebm_dir + "libwebm/"]) +# upstream uses c++11 +if (not env_webm.msvc): + env_webm.Append(CCFLAGS="-std=c++11") + # also requires libogg, libvorbis and libopus if env['builtin_libogg']: env_webm.Append(CPPPATH=["#thirdparty/libogg"]) diff --git a/modules/webm/doc_classes/ResourceImporterWebm.xml b/modules/webm/doc_classes/ResourceImporterWebm.xml index 7c8e1a46b1..0cfab1baf0 100644 --- a/modules/webm/doc_classes/ResourceImporterWebm.xml +++ b/modules/webm/doc_classes/ResourceImporterWebm.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourceImporterWebm" inherits="ResourceImporter" category="Core" version="3.1-dev"> +<class name="ResourceImporterWebm" inherits="ResourceImporter" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/webm/doc_classes/VideoStreamWebm.xml b/modules/webm/doc_classes/VideoStreamWebm.xml index d52e2324a1..c02a7a8016 100644 --- a/modules/webm/doc_classes/VideoStreamWebm.xml +++ b/modules/webm/doc_classes/VideoStreamWebm.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VideoStreamWebm" inherits="VideoStream" category="Core" version="3.1-dev"> +<class name="VideoStreamWebm" inherits="VideoStream" category="Core" version="3.1"> <brief_description> </brief_description> <description> diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub index 0ebafa022d..b09c232b3c 100644 --- a/modules/webm/libvpx/SCsub +++ b/modules/webm/libvpx/SCsub @@ -340,7 +340,7 @@ if webm_simd_optimizations == False: env_libvpx.add_source_files(env.modules_sources, libvpx_sources) if webm_cpu_x86: - is_clang_or_gcc = ('gcc' in env["CC"]) or ('clang' in env["CC"]) + is_clang_or_gcc = ('gcc' in env["CC"]) or ('clang' in env["CC"]) or ("OSXCROSS_ROOT" in os.environ) env_libvpx_mmx = env_libvpx.Clone() if cpu_bits == '32' and is_clang_or_gcc: diff --git a/modules/websocket/SCsub b/modules/websocket/SCsub index 1a36e05863..b36f1beacd 100644 --- a/modules/websocket/SCsub +++ b/modules/websocket/SCsub @@ -35,7 +35,6 @@ thirdparty_sources = [ "handshake.c", "header.c", "libwebsockets.c", - "minilex.c", "output.c", "pollfd.c", "service.c", @@ -69,11 +68,11 @@ else: env_lws.Append(CPPPATH=[thirdparty_dir]) wrapper_includes = ["#thirdparty/lws/mbedtls_wrapper/include/" + inc for inc in ["internal", "openssl", "platform", ""]] - env_lws.Append(CPPPATH=wrapper_includes) + env_lws.Prepend(CPPPATH=wrapper_includes) if env['builtin_mbedtls']: mbedtls_includes = "#thirdparty/mbedtls/include" - env_lws.Append(CPPPATH=[mbedtls_includes]) + env_lws.Prepend(CPPPATH=[mbedtls_includes]) if env_lws["platform"] == "windows" or env_lws["platform"] == "uwp": env_lws.Append(CPPPATH=[thirdparty_dir + helper_dir]) diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index 38fe520fc1..1405fa98b0 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h index 8801f37007..6c2fa23b53 100644 --- a/modules/websocket/emws_client.h +++ b/modules/websocket/emws_client.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index 93665e6428..d3330d683c 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h index a50d1874ba..e06f725265 100644 --- a/modules/websocket/emws_peer.h +++ b/modules/websocket/emws_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/emws_server.cpp b/modules/websocket/emws_server.cpp index 60e9133225..c9ddae0c8c 100644 --- a/modules/websocket/emws_server.cpp +++ b/modules/websocket/emws_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/emws_server.h b/modules/websocket/emws_server.h index 59f1d76346..aa089ea40d 100644 --- a/modules/websocket/emws_server.h +++ b/modules/websocket/emws_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/lws_client.cpp b/modules/websocket/lws_client.cpp index 604b1886ad..2220c9adf2 100644 --- a/modules/websocket/lws_client.cpp +++ b/modules/websocket/lws_client.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,6 +31,7 @@ #include "lws_client.h" #include "core/io/ip.h" +#include "core/io/stream_peer_ssl.h" Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) { @@ -64,6 +65,9 @@ Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, info.uid = -1; //info.ws_ping_pong_interval = 5; info.user = _lws_ref; +#if defined(LWS_OPENSSL_SUPPORT) + info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; +#endif context = lws_create_context(&info); if (context == NULL) { @@ -87,7 +91,14 @@ Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, i.host = hbuf; i.path = pbuf; i.port = p_port; - i.ssl_connection = p_ssl; + + if (p_ssl) { + i.ssl_connection = LCCSCF_USE_SSL; + if (!verify_ssl) + i.ssl_connection |= LCCSCF_ALLOW_SELFSIGNED; + } else { + i.ssl_connection = 0; + } lws_client_connect_via_info(&i); return OK; @@ -104,6 +115,13 @@ int LWSClient::_handle_cb(struct lws *wsi, enum lws_callback_reasons reason, voi LWSPeer::PeerData *peer_data = (LWSPeer::PeerData *)user; switch (reason) { + case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: { + PoolByteArray arr = StreamPeerSSL::get_project_cert_array(); + if (arr.size() > 0) + SSL_CTX_add_client_CA((SSL_CTX *)user, d2i_X509(NULL, &arr.read()[0], arr.size())); + else if (verify_ssl) + WARN_PRINTS("No CA cert specified in project settings, SSL will not work"); + } break; case LWS_CALLBACK_CLIENT_ESTABLISHED: peer->set_wsi(wsi); diff --git a/modules/websocket/lws_client.h b/modules/websocket/lws_client.h index 2e082175df..8850683cb5 100644 --- a/modules/websocket/lws_client.h +++ b/modules/websocket/lws_client.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/lws_helper.h b/modules/websocket/lws_helper.h index ac0c340aa9..a850a545d3 100644 --- a/modules/websocket/lws_helper.h +++ b/modules/websocket/lws_helper.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -108,7 +108,7 @@ static bool _lws_poll(struct lws_context *context, _LWSRef *ref) { static void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback, PoolVector<String> p_names, _LWSRef **r_lws_ref) { /* the input strings might go away after this call, * we need to copy them. Will clear them when - * detroying the context */ + * destroying the context */ int i; int len = p_names.size(); size_t data_size = sizeof(struct LWSPeer::PeerData); diff --git a/modules/websocket/lws_peer.cpp b/modules/websocket/lws_peer.cpp index fdaa79f9d4..ba45d7688f 100644 --- a/modules/websocket/lws_peer.cpp +++ b/modules/websocket/lws_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/lws_peer.h b/modules/websocket/lws_peer.h index 0a62b65d24..e96b38b168 100644 --- a/modules/websocket/lws_peer.h +++ b/modules/websocket/lws_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/lws_server.cpp b/modules/websocket/lws_server.cpp index 8a47ba557d..94fe4231ae 100644 --- a/modules/websocket/lws_server.cpp +++ b/modules/websocket/lws_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/lws_server.h b/modules/websocket/lws_server.h index 5f7ac4850a..de8f59e5ae 100644 --- a/modules/websocket/lws_server.h +++ b/modules/websocket/lws_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/register_types.cpp b/modules/websocket/register_types.cpp index 39d03ff1f0..721f3cc330 100644 --- a/modules/websocket/register_types.cpp +++ b/modules/websocket/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/register_types.h b/modules/websocket/register_types.h index 010d88789b..89ce93e286 100644 --- a/modules/websocket/register_types.h +++ b/modules/websocket/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_client.cpp b/modules/websocket/websocket_client.cpp index f92a386988..7701163085 100644 --- a/modules/websocket/websocket_client.cpp +++ b/modules/websocket/websocket_client.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,6 +32,8 @@ GDCINULL(WebSocketClient); WebSocketClient::WebSocketClient() { + + verify_ssl = true; } WebSocketClient::~WebSocketClient() { @@ -72,6 +74,16 @@ Error WebSocketClient::connect_to_url(String p_url, PoolVector<String> p_protoco return connect_to_host(host, path, port, ssl, p_protocols); } +void WebSocketClient::set_verify_ssl_enabled(bool p_verify_ssl) { + + verify_ssl = p_verify_ssl; +} + +bool WebSocketClient::is_verify_ssl_enabled() const { + + return verify_ssl; +} + bool WebSocketClient::is_server() const { return false; @@ -116,6 +128,10 @@ void WebSocketClient::_on_error() { void WebSocketClient::_bind_methods() { ClassDB::bind_method(D_METHOD("connect_to_url", "url", "protocols", "gd_mp_api"), &WebSocketClient::connect_to_url, DEFVAL(PoolVector<String>()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("disconnect_from_host"), &WebSocketClient::disconnect_from_host); + ClassDB::bind_method(D_METHOD("set_verify_ssl_enabled", "enabled"), &WebSocketClient::set_verify_ssl_enabled); + ClassDB::bind_method(D_METHOD("is_verify_ssl_enabled"), &WebSocketClient::is_verify_ssl_enabled); + + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "verify_ssl", PROPERTY_HINT_NONE, "", 0), "set_verify_ssl_enabled", "is_verify_ssl_enabled"); ADD_SIGNAL(MethodInfo("data_received")); ADD_SIGNAL(MethodInfo("connection_established", PropertyInfo(Variant::STRING, "protocol"))); diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h index 0e87825222..6165f37d40 100644 --- a/modules/websocket/websocket_client.h +++ b/modules/websocket/websocket_client.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,12 +41,16 @@ class WebSocketClient : public WebSocketMultiplayerPeer { protected: Ref<WebSocketPeer> _peer; + bool verify_ssl; static void _bind_methods(); public: Error connect_to_url(String p_url, PoolVector<String> p_protocols = PoolVector<String>(), bool gd_mp_api = false); + void set_verify_ssl_enabled(bool p_verify_ssl); + bool is_verify_ssl_enabled() const; + virtual void poll() = 0; virtual Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocol = PoolVector<String>()) = 0; virtual void disconnect_from_host() = 0; diff --git a/modules/websocket/websocket_macros.h b/modules/websocket/websocket_macros.h index b5c2159806..d27fb4d778 100644 --- a/modules/websocket/websocket_macros.h +++ b/modules/websocket/websocket_macros.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_multiplayer.cpp b/modules/websocket/websocket_multiplayer.cpp index 8cd4dff38b..b948c439df 100644 --- a/modules/websocket/websocket_multiplayer.cpp +++ b/modules/websocket/websocket_multiplayer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_multiplayer.h b/modules/websocket/websocket_multiplayer.h index e8e795e97f..8edfc5296e 100644 --- a/modules/websocket/websocket_multiplayer.h +++ b/modules/websocket/websocket_multiplayer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_peer.cpp b/modules/websocket/websocket_peer.cpp index a6fbb4481b..6324047846 100644 --- a/modules/websocket/websocket_peer.cpp +++ b/modules/websocket/websocket_peer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_peer.h b/modules/websocket/websocket_peer.h index f4d8ce3e38..ad451e9cc7 100644 --- a/modules/websocket/websocket_peer.h +++ b/modules/websocket/websocket_peer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp index ba77019f55..5746f61e10 100644 --- a/modules/websocket/websocket_server.cpp +++ b/modules/websocket/websocket_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h index db188811fd..360ff9e6d4 100644 --- a/modules/websocket/websocket_server.h +++ b/modules/websocket/websocket_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/SCsub b/platform/SCsub index e624f8e90f..2019a30be7 100644 --- a/platform/SCsub +++ b/platform/SCsub @@ -18,11 +18,10 @@ for platform in env.platform_apis: reg_apis_inc += '\n' reg_apis += '}\n\n' unreg_apis += '}\n' -f = open_utf8('register_platform_apis.gen.cpp', 'w') -f.write(reg_apis_inc) -f.write(reg_apis) -f.write(unreg_apis) -f.close() +with open_utf8('register_platform_apis.gen.cpp', 'w') as f: + f.write(reg_apis_inc) + f.write(reg_apis) + f.write(unreg_apis) platform_sources.append('register_platform_apis.gen.cpp') lib = env.add_library('platform', platform_sources) diff --git a/platform/android/AndroidManifest.xml.template b/platform/android/AndroidManifest.xml.template index 9d8eb951c4..3e42b7a3cd 100644 --- a/platform/android/AndroidManifest.xml.template +++ b/platform/android/AndroidManifest.xml.template @@ -16,7 +16,8 @@ android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:launchMode="singleTask" android:screenOrientation="landscape" - android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize"> + android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize" + android:resizeableActivity="false"> <intent-filter> <action android:name="android.intent.action.MAIN" /> @@ -31,7 +32,7 @@ $$ADD_APPLICATION_CHUNKS$$ </application> - <uses-feature android:glEsVersion="0x00030000"/> + <uses-feature android:glEsVersion="0x00030000" android:required="true" /> $$ADD_PERMISSION_CHUNKS$$ <uses-permission android:name="godot.ACCESS_CHECKIN_PROPERTIES"/> diff --git a/platform/android/SCsub b/platform/android/SCsub index d2285a82dd..8c08289932 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -41,10 +41,8 @@ prog = None abspath = env.Dir(".").abspath -gradle_basein = open_utf8(abspath + "/build.gradle.template", "r") -gradle_baseout = open_utf8(abspath + "/java/build.gradle", "w") - -gradle_text = gradle_basein.read() +with open_utf8(abspath + "/build.gradle.template", "r") as gradle_basein: + gradle_text = gradle_basein.read() gradle_maven_flat_text = "" if len(env.android_flat_dirs) > 0: @@ -131,17 +129,19 @@ gradle_text = gradle_text.replace("$$GRADLE_DEFAULT_CONFIG$$", gradle_default_co gradle_text = gradle_text.replace("$$GRADLE_PLUGINS$$", gradle_plugins) gradle_text = gradle_text.replace("$$GRADLE_CLASSPATH$$", gradle_classpath) -gradle_baseout.write(gradle_text) -gradle_baseout.close() +with open_utf8(abspath + "/java/build.gradle", "w") as gradle_baseout: + gradle_baseout.write(gradle_text) + +with open_utf8(abspath + "/AndroidManifest.xml.template", "r") as pp_basein: + manifest = pp_basein.read() -pp_basein = open_utf8(abspath + "/AndroidManifest.xml.template", "r") -pp_baseout = open_utf8(abspath + "/java/AndroidManifest.xml", "w") -manifest = pp_basein.read() manifest = manifest.replace("$$ADD_APPLICATION_CHUNKS$$", env.android_manifest_chunk) manifest = manifest.replace("$$ADD_PERMISSION_CHUNKS$$", env.android_permission_chunk) manifest = manifest.replace("$$ADD_APPATTRIBUTE_CHUNKS$$", env.android_appattributes_chunk) -pp_baseout.write(manifest) + +with open_utf8(abspath + "/java/AndroidManifest.xml", "w") as pp_baseout: + pp_baseout.write(manifest) lib = env_android.add_shared_library("#bin/libgodot", [android_objects], SHLIBSUFFIX=env["SHLIBSUFFIX"]) diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp index bc77a4e729..e6bd3ff253 100644 --- a/platform/android/audio_driver_opensl.cpp +++ b/platform/android/audio_driver_opensl.cpp @@ -271,4 +271,5 @@ AudioDriverOpenSL::AudioDriverOpenSL() { s_ad = this; mutex = Mutex::create(); //NULL; pause = false; + active = false; } diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 2a61f8d873..6d9f0a7e9a 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -257,7 +257,7 @@ class EditorExportAndroid : public EditorExportPlatform { if (dpos == -1) continue; d = d.substr(0, dpos).strip_edges(); - //print_line("found devuce: "+d); + //print_line("found device: "+d); ldevices.push_back(d); } @@ -301,8 +301,7 @@ class EditorExportAndroid : public EditorExportPlatform { args.push_back("-s"); args.push_back(d.id); args.push_back("shell"); - args.push_back("cat"); - args.push_back("/system/build.prop"); + args.push_back("getprop"); int ec; String dp; @@ -315,7 +314,14 @@ class EditorExportAndroid : public EditorExportPlatform { d.api_level = 0; for (int j = 0; j < props.size(); j++) { + // got information by `shell cat /system/build.prop` before and its format is "property=value" + // it's now changed to use `shell getporp` because of permission issue with Android 8.0 and above + // its format is "[property]: [value]" so changed it as like build.prop String p = props[j]; + p = p.replace("]: ", "="); + p = p.replace("[", ""); + p = p.replace("]", ""); + if (p.begins_with("ro.product.model=")) { device = p.get_slice("=", 1).strip_edges(); } else if (p.begins_with("ro.product.brand=")) { @@ -996,7 +1002,7 @@ public: public: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { - // Reenable when a GLES 2.0 backend is readded + // Re-enable when a GLES 2.0 backend is read /*int api = p_preset->get("graphics/api"); if (api == 0) r_features->push_back("etc"); diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 9baf58c3eb..579c06f76b 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -936,6 +936,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *en } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj) { + if (step == 0) + return; + os_android->main_loop_request_go_back(); } @@ -976,6 +979,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jobject obj, jint ev, jint pointer, jint count, jintArray positions) { + if (step == 0) + return; + Vector<OS_Android::TouchPos> points; for (int i = 0; i < count; i++) { @@ -1250,6 +1256,8 @@ static unsigned int android_get_keysym(unsigned int p_code) { } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jobject obj, jint p_device, jint p_button, jboolean p_pressed) { + if (step == 0) + return; OS_Android::JoypadEvent jevent; jevent.device = p_device; @@ -1261,6 +1269,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jobject obj, jint p_device, jint p_axis, jfloat p_value) { + if (step == 0) + return; OS_Android::JoypadEvent jevent; jevent.device = p_device; @@ -1272,6 +1282,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y) { + if (step == 0) + return; + OS_Android::JoypadEvent jevent; jevent.device = p_device; jevent.type = OS_Android::JOY_EVENT_HAT; @@ -1301,6 +1314,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged( } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { + if (step == 0) + return; Ref<InputEventKey> ievent; ievent.instance(); @@ -1344,14 +1359,18 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jobject obj) { - if (os_android && step > 0) - os_android->main_loop_focusin(); + if (step == 0) + return; + + os_android->main_loop_focusin(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jobject obj) { - if (os_android && step > 0) - os_android->main_loop_focusout(); + if (step == 0) + return; + + os_android->main_loop_focusout(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jobject obj) { diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 67ce796279..5557c1de44 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -130,8 +130,6 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int if (gfx_init_func) gfx_init_func(gfx_init_ud, use_gl2); - AudioDriverManager::add_driver(&audio_driver_android); - RasterizerGLES3::register_config(); RasterizerGLES3::make_current(); @@ -775,6 +773,8 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI Vector<Logger *> loggers; loggers.push_back(memnew(AndroidLogger)); _set_logger(memnew(CompositeLogger(loggers))); + + AudioDriverManager::add_driver(&audio_driver_android); } OS_Android::~OS_Android() { diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub index 6b5f30dc41..b96bec16b4 100644 --- a/platform/iphone/SCsub +++ b/platform/iphone/SCsub @@ -1,4 +1,5 @@ #!/usr/bin/env python +import os Import('env') @@ -21,6 +22,10 @@ ios_lib = env_ios.add_library('iphone', iphone_lib) def combine_libs(target=None, source=None, env=None): lib_path = target[0].srcnode().abspath - env.Execute('$IPHONEPATH/usr/bin/libtool -static -o "' + lib_path + '" ' + ' '.join([('"' + lib.srcnode().abspath + '"') for lib in source])) + if ("OSXCROSS_IOS" in os.environ): + libtool = '$IPHONEPATH/usr/bin/${ios_triple}libtool' + else: + libtool = "$IPHONEPATH/usr/bin/libtool" + env.Execute(libtool + ' -static -o "' + lib_path + '" ' + ' '.join([('"' + lib.srcnode().abspath + '"') for lib in source])) combine_command = env_ios.Command('#bin/libgodot' + env_ios['LIBSUFFIX'], [ios_lib] + env_ios['LIBS'], combine_libs) diff --git a/platform/iphone/icloud.mm b/platform/iphone/icloud.mm index 7508a480ce..a9748bf562 100644 --- a/platform/iphone/icloud.mm +++ b/platform/iphone/icloud.mm @@ -131,6 +131,8 @@ Variant nsobject_to_variant(NSObject *object) { return Variant([num floatValue]); } else if (strcmp([num objCType], @encode(double)) == 0) { return Variant((float)[num doubleValue]); + } else { + return Variant(); } } else if ([object isKindOfClass:[NSDate class]]) { //this is a type that icloud supports...but how did you submit it in the first place? diff --git a/platform/iphone/in_app_store.h b/platform/iphone/in_app_store.h index 7d53eaae20..353438676d 100644 --- a/platform/iphone/in_app_store.h +++ b/platform/iphone/in_app_store.h @@ -46,6 +46,7 @@ class InAppStore : public Object { public: Error request_product_info(Variant p_params); + Error restore_purchases(); Error purchase(Variant p_params); int get_pending_event_count(); diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm index 9bb3d7d3fa..6fa189e917 100644 --- a/platform/iphone/in_app_store.mm +++ b/platform/iphone/in_app_store.mm @@ -63,6 +63,7 @@ InAppStore *InAppStore::instance = NULL; void InAppStore::_bind_methods() { ClassDB::bind_method(D_METHOD("request_product_info"), &InAppStore::request_product_info); + ClassDB::bind_method(D_METHOD("restore_purchases"), &InAppStore::restore_purchases); ClassDB::bind_method(D_METHOD("purchase"), &InAppStore::purchase); ClassDB::bind_method(D_METHOD("get_pending_event_count"), &InAppStore::get_pending_event_count); @@ -153,6 +154,14 @@ Error InAppStore::request_product_info(Variant p_params) { return OK; }; +Error InAppStore::restore_purchases() { + + printf("restoring purchases!\n"); + [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; + + return OK; +}; + @interface TransObserver : NSObject <SKPaymentTransactionObserver> { }; @end @@ -236,6 +245,11 @@ Error InAppStore::request_product_info(Variant p_params) { printf("status transaction restored!\n"); String pid = String::utf8([transaction.originalTransaction.payment.productIdentifier UTF8String]); InAppStore::get_singleton()->_record_purchase(pid); + Dictionary ret; + ret["type"] = "restore"; + ret["result"] = "ok"; + ret["product_id"] = pid; + InAppStore::get_singleton()->_post_event(ret); [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; } break; default: { diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index c284ab6905..c4c59431f2 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -123,7 +123,6 @@ Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p // reset this to what it should be, it will have been set to 0 after visual_server->init() is called RasterizerStorageGLES3::system_fbo = gl_view_base_fb; - AudioDriverManager::add_driver(&audio_driver); AudioDriverManager::initialize(p_audio_driver); input = memnew(InputDefault); @@ -632,6 +631,8 @@ OSIPhone::OSIPhone(int width, int height, String p_data_dir) { loggers.push_back(memnew(StdLogger)); #endif _set_logger(memnew(CompositeLogger(loggers))); + + AudioDriverManager::add_driver(&audio_driver); }; OSIPhone::~OSIPhone() { diff --git a/platform/iphone/platform_config.h b/platform/iphone/platform_config.h index d205c7da83..d9fd61fb6e 100644 --- a/platform/iphone/platform_config.h +++ b/platform/iphone/platform_config.h @@ -30,6 +30,7 @@ #include <alloca.h> +#define GLES2_INCLUDE_H <ES2/gl.h> #define GLES3_INCLUDE_H <ES3/gl.h> #define PLATFORM_REFCOUNT diff --git a/platform/iphone/power_iphone.cpp b/platform/iphone/power_iphone.cpp index 95a9aa9705..7f9dadc363 100644 --- a/platform/iphone/power_iphone.cpp +++ b/platform/iphone/power_iphone.cpp @@ -30,7 +30,7 @@ #include "power_iphone.h" -bool OS::PowerState::UpdatePowerInfo() { +bool PowerIphone::UpdatePowerInfo() { return false; } diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index 66a8a8d93c..5991075e29 100644 --- a/platform/javascript/SCsub +++ b/platform/javascript/SCsub @@ -3,38 +3,35 @@ Import('env') javascript_files = [ - "os_javascript.cpp", - "audio_driver_javascript.cpp", - "javascript_main.cpp", - "power_javascript.cpp", - "http_client_javascript.cpp", - "javascript_eval.cpp", + 'audio_driver_javascript.cpp', + 'http_client_javascript.cpp', + 'javascript_eval.cpp', + 'javascript_main.cpp', + 'os_javascript.cpp', ] -env_javascript = env.Clone() -if env['target'] == "profile": - env_javascript.Append(CPPFLAGS=['-DPROFILER_ENABLED']) - -javascript_objects = [] -for x in javascript_files: - javascript_objects.append(env_javascript.Object(x)) - -env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_main_after_fs_sync','_send_notification']\""]) - -target_dir = env.Dir("#bin") -build = env.add_program(['#bin/godot', target_dir.File('godot' + env['PROGSUFFIX'] + '.wasm')], javascript_objects, PROGSUFFIX=env['PROGSUFFIX'] + '.js'); +build = env.add_program(['#bin/godot${PROGSUFFIX}.js', '#bin/godot${PROGSUFFIX}.wasm'], javascript_files); js, wasm = build -js_libraries = [] -js_libraries.append(env.File('http_request.js')) +js_libraries = [ + 'http_request.js', +] for lib in js_libraries: - env.Append(LINKFLAGS=['--js-library', lib.path]) + env.Append(LINKFLAGS=['--js-library', env.File(lib).path]) env.Depends(build, js_libraries) wrapper_start = env.File('pre.js') wrapper_end = env.File('engine.js') -js_final = env.Textfile('#bin/godot', [wrapper_start, js, wrapper_end], TEXTFILESUFFIX=env['PROGSUFFIX'] + '.wrapped.js') - -zip_dir = target_dir.Dir('.javascript_zip') -zip_files = env.InstallAs([zip_dir.File('godot.js'), zip_dir.File('godot.wasm'), zip_dir.File('godot.html')], [js_final, wasm, '#misc/dist/html/default.html']) -Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX'] + env['ZIPSUFFIX'], ZIPROOT=zip_dir, ZIPCOMSTR="Archving $SOURCES as $TARGET") +js_wrapped = env.Textfile('#bin/godot', [wrapper_start, js, wrapper_end], TEXTFILESUFFIX='${PROGSUFFIX}.wrapped.js') + +zip_dir = env.Dir('#bin/.javascript_zip') +zip_files = env.InstallAs([ + zip_dir.File('godot.js'), + zip_dir.File('godot.wasm'), + zip_dir.File('godot.html') +], [ + js_wrapped, + wasm, + '#misc/dist/html/default.html' +]) +env.Zip('#bin/godot', zip_files, ZIPROOT=zip_dir, ZIPSUFFIX='${PROGSUFFIX}${ZIPSUFFIX}', ZIPCOMSTR='Archving $SOURCES as $TARGET') diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 7e6a1518ed..a48cb872ee 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -8,23 +8,22 @@ def is_active(): def get_name(): - return "JavaScript" + return 'JavaScript' def can_build(): - - return ("EMSCRIPTEN_ROOT" in os.environ or "EMSCRIPTEN" in os.environ) + return 'EM_CONFIG' in os.environ or os.path.exists(os.path.expanduser('~/.emscripten')) def get_opts(): from SCons.Variables import BoolVariable return [ + # eval() can be a security concern, so it can be disabled. BoolVariable('javascript_eval', 'Enable JavaScript eval interface', True), ] def get_flags(): - return [ ('tools', False), ('module_theora_enabled', False), @@ -36,24 +35,11 @@ def get_flags(): ] -def create(env): - - # remove Windows' .exe suffix - return env.Clone(tools=['textfile', 'zip'], PROGSUFFIX='') - - -def escape_sources_backslashes(target, source, env, for_signature): - return [path.replace('\\','\\\\') for path in env.GetBuildPath(source)] - -def escape_target_backslashes(target, source, env, for_signature): - return env.GetBuildPath(target[0]).replace('\\','\\\\') - - def configure(env): ## Build type - if (env["target"] == "release"): + if env['target'] == 'release' or env['target'] == 'profile': # Use -Os to prioritize optimizing for reduced file size. This is # particularly valuable for the web platform because it directly # decreases download time. @@ -62,65 +48,102 @@ def configure(env): # run-time performance. env.Append(CCFLAGS=['-Os']) env.Append(LINKFLAGS=['-Os']) - - elif (env["target"] == "release_debug"): - env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED']) - env.Append(LINKFLAGS=['-O2', '-s', 'ASSERTIONS=1']) - # retain function names at the cost of file size, for backtraces and profiling + if env['target'] == 'profile': + env.Append(LINKFLAGS=['--profiling-funcs']) + + elif env['target'] == 'release_debug': + env.Append(CPPDEFINES=['DEBUG_ENABLED']) + env.Append(CCFLAGS=['-O2']) + env.Append(LINKFLAGS=['-O2']) + # Retain function names for backtraces at the cost of file size. env.Append(LINKFLAGS=['--profiling-funcs']) - elif (env["target"] == "debug"): - env.Append(CCFLAGS=['-O1', '-D_DEBUG', '-g', '-DDEBUG_ENABLED']) + elif env['target'] == 'debug': + env.Append(CPPDEFINES=['DEBUG_ENABLED']) + env.Append(CCFLAGS=['-O1', '-g']) env.Append(LINKFLAGS=['-O1', '-g']) + env.Append(LINKFLAGS=['-s', 'ASSERTIONS=1']) ## Compiler configuration env['ENV'] = os.environ - if ("EMSCRIPTEN_ROOT" in os.environ): - env.PrependENVPath('PATH', os.environ['EMSCRIPTEN_ROOT']) - elif ("EMSCRIPTEN" in os.environ): - env.PrependENVPath('PATH', os.environ['EMSCRIPTEN']) - env['CC'] = 'emcc' - env['CXX'] = 'em++' - env['LINK'] = 'emcc' - env['RANLIB'] = 'emranlib' - # Emscripten's ar has issues with duplicate file names, so use cc - env['AR'] = 'emcc' - env['ARFLAGS'] = '-o' - - if (os.name == 'nt'): - # use TempFileMunge on Windows since some commands get too long for - # cmd.exe even with spawn_fix - # need to escape backslashes for this - env['ESCAPED_SOURCES'] = escape_sources_backslashes - env['ESCAPED_TARGET'] = escape_target_backslashes - env['ARCOM'] = '${TEMPFILE("%s")}' % env['ARCOM'].replace('$SOURCES', '$ESCAPED_SOURCES').replace('$TARGET', '$ESCAPED_TARGET') + em_config_file = os.getenv('EM_CONFIG') or os.path.expanduser('~/.emscripten') + if not os.path.exists(em_config_file): + raise RuntimeError("Emscripten configuration file '%s' does not exist" % em_config_file) + with open(em_config_file) as f: + em_config = {} + try: + # Emscripten configuration file is a Python file with simple assignments. + exec(f.read(), em_config) + except StandardError as e: + raise RuntimeError("Emscripten configuration file '%s' is invalid:\n%s" % (em_config_file, e)) + if 'EMSCRIPTEN_ROOT' not in em_config: + raise RuntimeError("'EMSCRIPTEN_ROOT' missing in Emscripten configuration file '%s'" % em_config_file) + env.PrependENVPath('PATH', em_config['EMSCRIPTEN_ROOT']) + + env['CC'] = 'emcc' + env['CXX'] = 'em++' + env['LINK'] = 'emcc' + + # Emscripten's ar has issues with duplicate file names, so use cc. + env['AR'] = 'emcc' + env['ARFLAGS'] = '-o' + # emranlib is a noop, so it's safe to use with AR=emcc. + env['RANLIB'] = 'emranlib' + + # Use TempFileMunge since some AR invocations are too long for cmd.exe. + # Use POSIX-style paths, required with TempFileMunge. + env['ARCOM_POSIX'] = env['ARCOM'].replace( + '$TARGET', '$TARGET.posix').replace( + '$SOURCES', '$SOURCES.posix') + env['ARCOM'] = '${TEMPFILE(ARCOM_POSIX)}' + + # All intermediate files are just LLVM bitcode. + env['OBJPREFIX'] = '' env['OBJSUFFIX'] = '.bc' + env['PROGPREFIX'] = '' + # Program() output consists of multiple files, so specify suffixes manually at builder. + env['PROGSUFFIX'] = '' + env['LIBPREFIX'] = 'lib' env['LIBSUFFIX'] = '.bc' + env['LIBPREFIXES'] = ['$LIBPREFIX'] + env['LIBSUFFIXES'] = ['$LIBSUFFIX'] ## Compile flags env.Append(CPPPATH=['#platform/javascript']) - env.Append(CPPFLAGS=['-DJAVASCRIPT_ENABLED', '-DUNIX_ENABLED', '-DPTHREAD_NO_RENAME', '-DTYPED_METHOD_BIND', '-DNO_THREADS']) - env.Append(CPPFLAGS=['-DGLES3_ENABLED']) + env.Append(CPPDEFINES=['JAVASCRIPT_ENABLED', 'UNIX_ENABLED']) - # These flags help keep the file size down - env.Append(CPPFLAGS=["-fno-exceptions", '-DNO_SAFE_CAST', '-fno-rtti']) + # No multi-threading (SharedArrayBuffer) available yet, + # once feasible also consider memory buffer size issues. + env.Append(CPPDEFINES=['NO_THREADS']) + + # These flags help keep the file size down. + env.Append(CCFLAGS=['-fno-exceptions', '-fno-rtti']) + # Don't use dynamic_cast, necessary with no-rtti. + env.Append(CPPDEFINES=['NO_SAFE_CAST']) if env['javascript_eval']: - env.Append(CPPFLAGS=['-DJAVASCRIPT_EVAL_ENABLED']) + env.Append(CPPDEFINES=['JAVASCRIPT_EVAL_ENABLED']) ## Link flags env.Append(LINKFLAGS=['-s', 'BINARYEN=1']) + + # Allow increasing memory buffer size during runtime. This is efficient + # when using WebAssembly (in comparison to asm.js) and works well for + # us since we don't know requirements at compile-time. env.Append(LINKFLAGS=['-s', 'ALLOW_MEMORY_GROWTH=1']) + + # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1. env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1']) - env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS="[\'FS\']"']) env.Append(LINKFLAGS=['-s', 'INVOKE_RUN=0']) + + # TODO: Reevaluate usage of this setting now that engine.js manages engine runtime. env.Append(LINKFLAGS=['-s', 'NO_EXIT_RUNTIME=1']) - # TODO: Move that to opus module's config + # TODO: Move that to opus module's config. if 'module_opus_enabled' in env and env['module_opus_enabled']: - env.opus_fixed_point = "yes" + env.opus_fixed_point = 'yes' diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js index bca1851f40..e4839af433 100644 --- a/platform/javascript/engine.js +++ b/platform/javascript/engine.js @@ -1,3 +1,5 @@ + exposedLibs['PATH'] = PATH; + exposedLibs['FS'] = FS; return Module; }, }; @@ -12,6 +14,13 @@ var loadingFiles = {}; + function getPathLeaf(path) { + + while (path.endsWith('/')) + path = path.slice(0, -1); + return path.slice(path.lastIndexOf('/') + 1); + } + function getBasePath(path) { if (path.endsWith('/')) @@ -23,14 +32,15 @@ function getBaseName(path) { - path = getBasePath(path); - return path.slice(path.lastIndexOf('/') + 1); + return getPathLeaf(getBasePath(path)); } Engine = function Engine() { this.rtenv = null; + var LIBS = {}; + var initPromise = null; var unloadAfterInit = true; @@ -80,11 +90,11 @@ return new Promise(function(resolve, reject) { rtenvProps.onRuntimeInitialized = resolve; rtenvProps.onAbort = reject; - rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps); + rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps, LIBS); }); } - this.preloadFile = function(pathOrBuffer, bufferFilename) { + this.preloadFile = function(pathOrBuffer, destPath) { if (pathOrBuffer instanceof ArrayBuffer) { pathOrBuffer = new Uint8Array(pathOrBuffer); @@ -93,14 +103,14 @@ } if (pathOrBuffer instanceof Uint8Array) { preloadedFiles.push({ - name: bufferFilename, + path: destPath, buffer: pathOrBuffer }); return Promise.resolve(); } else if (typeof pathOrBuffer === 'string') { return loadPromise(pathOrBuffer, preloadProgressTracker).then(function(xhr) { preloadedFiles.push({ - name: pathOrBuffer, + path: destPath || pathOrBuffer, buffer: xhr.response }); }); @@ -119,7 +129,12 @@ this.startGame = function(mainPack) { executableName = getBaseName(mainPack); - return Promise.all([this.init(getBasePath(mainPack)), this.preloadFile(mainPack)]).then( + return Promise.all([ + // Load from directory, + this.init(getBasePath(mainPack)), + // ...but write to root where the engine expects it. + this.preloadFile(mainPack, getPathLeaf(mainPack)) + ]).then( Function.prototype.apply.bind(synchronousStart, this, []) ); }; @@ -138,18 +153,6 @@ } var actualCanvas = this.rtenv.canvas; - var testContext = false; - var testCanvas; - try { - testCanvas = document.createElement('canvas'); - testContext = testCanvas.getContext('webgl2') || testCanvas.getContext('experimental-webgl2'); - } catch (e) {} - if (!testContext) { - throw new Error("WebGL 2 not available"); - } - testCanvas = null; - testContext = null; - // canvas can grab focus on click if (actualCanvas.tabIndex < 0) { actualCanvas.tabIndex = 0; @@ -175,7 +178,16 @@ this.rtenv.thisProgram = executableName || getBaseName(basePath); preloadedFiles.forEach(function(file) { - this.rtenv.FS.createDataFile('/', file.name, new Uint8Array(file.buffer), true, true, true); + var dir = LIBS.PATH.dirname(file.path); + try { + LIBS.FS.stat(dir); + } catch (e) { + if (e.code !== 'ENOENT') { + throw e; + } + LIBS.FS.mkdirTree(dir); + } + LIBS.FS.createDataFile('/', file.path, new Uint8Array(file.buffer), true, true, true); }, this); preloadedFiles = null; @@ -273,6 +285,20 @@ Engine.RuntimeEnvironment = engine.RuntimeEnvironment; + Engine.isWebGLAvailable = function(majorVersion = 1) { + + var testContext = false; + try { + var testCanvas = document.createElement('canvas'); + if (majorVersion === 1) { + testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl'); + } else if (majorVersion === 2) { + testContext = testCanvas.getContext('webgl2') || testCanvas.getContext('experimental-webgl2'); + } + } catch (e) {} + return !!testContext; + }; + Engine.load = function(newBasePath) { if (newBasePath !== undefined) basePath = getBasePath(newBasePath); diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp index 118a77835e..8d90e01ae1 100644 --- a/platform/javascript/http_client_javascript.cpp +++ b/platform/javascript/http_client_javascript.cpp @@ -88,7 +88,7 @@ Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Ve ERR_FAIL_COND_V(port < 0, ERR_UNCONFIGURED); ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER); - String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + "/" + p_url; + String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + p_url; godot_xhr_reset(xhr_id); godot_xhr_open(xhr_id, _methods[p_method], url.utf8().get_data(), username.empty() ? NULL : username.utf8().get_data(), diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index e85fe0800f..54d4755bd7 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -40,7 +40,7 @@ static void main_loop() { os->main_loop_iterate(); } -extern "C" void main_after_fs_sync(char *p_idbfs_err) { +extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) { String idbfs_err = String::utf8(p_idbfs_err); if (!idbfs_err.empty()) { diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index e226ab6332..a275fb7929 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -33,6 +33,7 @@ #include "core/engine.h" #include "core/io/file_access_buffered_fa.h" #include "dom_keys.h" +#include "drivers/gles2/rasterizer_gles2.h" #include "drivers/gles3/rasterizer_gles3.h" #include "drivers/unix/dir_access_unix.h" #include "drivers/unix/file_access_unix.h" @@ -57,12 +58,19 @@ static void dom2godot_mod(T emscripten_event_ptr, Ref<InputEventWithModifiers> g int OS_JavaScript::get_video_driver_count() const { - return 1; + return VIDEO_DRIVER_MAX; } const char *OS_JavaScript::get_video_driver_name(int p_driver) const { - return "GLES3"; + switch (p_driver) { + case VIDEO_DRIVER_GLES3: + return "GLES3"; + case VIDEO_DRIVER_GLES2: + return "GLES2"; + } + ERR_EXPLAIN("Invalid video driver index " + itos(p_driver)); + ERR_FAIL_V(NULL); } int OS_JavaScript::get_audio_driver_count() const { @@ -405,14 +413,13 @@ static EM_BOOL joy_callback_func(int p_type, const EmscriptenGamepadEvent *p_eve return false; } -extern "C" { -void send_notification(int notif) { +extern "C" EMSCRIPTEN_KEEPALIVE void send_notification(int notif) { + if (notif == MainLoop::NOTIFICATION_WM_MOUSE_ENTER || notif == MainLoop::NOTIFICATION_WM_MOUSE_EXIT) { _cursor_inside_canvas = notif == MainLoop::NOTIFICATION_WM_MOUSE_ENTER; } OS_JavaScript::get_singleton()->get_main_loop()->notification(notif); } -} Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { @@ -422,8 +429,21 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, emscripten_webgl_init_context_attributes(&attributes); attributes.alpha = false; attributes.antialias = false; - attributes.majorVersion = 2; + ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER); + switch (p_video_driver) { + case VIDEO_DRIVER_GLES3: + attributes.majorVersion = 2; + RasterizerGLES3::register_config(); + RasterizerGLES3::make_current(); + break; + case VIDEO_DRIVER_GLES2: + attributes.majorVersion = 1; + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + break; + } EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes); + ERR_EXPLAIN("WebGL " + itos(attributes.majorVersion) + ".0 not available"); ERR_FAIL_COND_V(emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS, ERR_UNAVAILABLE); video_mode = p_desired; @@ -447,12 +467,8 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, print_line("Init Audio"); - AudioDriverManager::add_driver(&audio_driver_javascript); AudioDriverManager::initialize(p_audio_driver); - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - print_line("Init VS"); visual_server = memnew(VisualServerRaster()); @@ -463,8 +479,6 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, input = memnew(InputDefault); _input = input; - power_manager = memnew(PowerJavascript); - #define EM_CHECK(ev) \ if (result != EMSCRIPTEN_RESULT_SUCCESS) \ ERR_PRINTS("Error while setting " #ev " callback: Code " + itos(result)) @@ -951,15 +965,21 @@ String OS_JavaScript::get_joy_guid(int p_device) const { } OS::PowerState OS_JavaScript::get_power_state() { - return power_manager->get_power_state(); + + WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to POWERSTATE_UNKNOWN"); + return OS::POWERSTATE_UNKNOWN; } int OS_JavaScript::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); + + WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to -1"); + return -1; } int OS_JavaScript::get_power_percent_left() { - return power_manager->get_power_percent_left(); + + WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to -1"); + return -1; } bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) { @@ -1012,6 +1032,8 @@ OS_JavaScript::OS_JavaScript(const char *p_execpath, GetUserDataDirFunc p_get_us Vector<Logger *> loggers; loggers.push_back(memnew(StdLogger)); _set_logger(memnew(CompositeLogger(loggers))); + + AudioDriverManager::add_driver(&audio_driver_javascript); } OS_JavaScript::~OS_JavaScript() { diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index f0ba9422e8..46eb1b3f13 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -36,7 +36,6 @@ #include "main/input_default.h" #include "os/input.h" #include "os/main_loop.h" -#include "power_javascript.h" #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" @@ -64,8 +63,6 @@ class OS_JavaScript : public OS_Unix { GetUserDataDirFunc get_user_data_dir_func; - PowerJavascript *power_manager; - static void _close_notification_funcs(const String &p_file, int p_flags); void process_joypads(); diff --git a/platform/javascript/pre.js b/platform/javascript/pre.js index 311aa44fda..02194bc75e 100644 --- a/platform/javascript/pre.js +++ b/platform/javascript/pre.js @@ -1,2 +1,2 @@ var Engine = { - RuntimeEnvironment: function(Module) { + RuntimeEnvironment: function(Module, exposedLibs) { diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 6a9fd6b134..1e9631fae0 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -59,7 +59,7 @@ def configure(env): # Mac OS X no longer runs on 32-bit since 10.7 which is unsupported since 2014 # As such, we only support 64-bit - env["bits"] = 64 + env["bits"] = "64" ## Compiler configuration @@ -93,6 +93,7 @@ def configure(env): env['AR'] = basecmd + "ar" env['RANLIB'] = basecmd + "ranlib" env['AS'] = basecmd + "as" + env.Append(CCFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define if (env["CXX"] == "clang++"): env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 7985a241e4..db265812fa 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -496,7 +496,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p if (use_dmg()) { String pack_path = tmp_app_path_name + "/Contents/Resources/" + pkg_name + ".pck"; Vector<SharedObject> shared_objects; - Error err = save_pack(p_preset, pack_path, &shared_objects); + err = save_pack(p_preset, pack_path, &shared_objects); // see if we can code sign our new package String identity = p_preset->get("codesign/identity"); @@ -504,7 +504,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p if (err == OK) { DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); for (int i = 0; i < shared_objects.size(); i++) { - da->copy(shared_objects[i].path, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file()); + err = da->copy(shared_objects[i].path, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file()); if (err == OK && identity != "") { err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file()); } @@ -549,7 +549,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p String pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".pck"); Vector<SharedObject> shared_objects; - Error err = save_pack(p_preset, pack_path, &shared_objects); + err = save_pack(p_preset, pack_path, &shared_objects); if (err == OK) { zipOpenNewFileInZip(dst_pkg_zip, @@ -581,7 +581,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } else { err = ERR_CANT_OPEN; } + } + if (err == OK) { //add shared objects for (int i = 0; i < shared_objects.size(); i++) { Vector<uint8_t> file = FileAccess::get_file_as_array(shared_objects[i].path); @@ -609,26 +611,32 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p zipClose(dst_pkg_zip, NULL); } - return OK; + return err; } bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { - bool valid = true; + bool valid = false; String err; - if (!exists_export_template("osx.zip", &err)) { - valid = false; + if (exists_export_template("osx.zip", &err)) { + valid = true; } - if (p_preset->get("custom_package/debug") != "" && !FileAccess::exists(p_preset->get("custom_package/debug"))) { - valid = false; - err += "Custom debug package not found.\n"; + if (p_preset->get("custom_package/debug") != "") { + if (FileAccess::exists(p_preset->get("custom_package/debug"))) { + valid = true; + } else { + err += "Custom debug package not found.\n"; + } } - if (p_preset->get("custom_package/release") != "" && !FileAccess::exists(p_preset->get("custom_package/release"))) { - valid = false; - err += "Custom release package not found.\n"; + if (p_preset->get("custom_package/release") != "") { + if (FileAccess::exists(p_preset->get("custom_package/release"))) { + valid = true; + } else { + err += "Custom release package not found.\n"; + } } if (!err.empty()) diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm index 6ccbaf896b..64116fa1e0 100644 --- a/platform/osx/godot_main_osx.mm +++ b/platform/osx/godot_main_osx.mm @@ -101,5 +101,5 @@ int main(int argc, char **argv) { Main::cleanup(); - return 0; + return os.get_exit_code(); }; diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index aa8db8f300..fee25e98cb 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -100,7 +100,7 @@ public: id context; CursorShape cursor_shape; - NSCursor *cursors[CURSOR_MAX] = { NULL }; + NSCursor *cursors[CURSOR_MAX]; MouseMode mouse_mode; String title; @@ -134,9 +134,6 @@ public: void _update_window(); protected: - virtual int get_video_driver_count() const; - virtual const char *get_video_driver_name(int p_driver) const; - virtual void initialize_core(); virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void finalize(); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 4c459772aa..0c5524dd08 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -31,6 +31,7 @@ #include "os_osx.h" #include "dir_access_osx.h" +#include "drivers/gles2/rasterizer_gles2.h" #include "drivers/gles3/rasterizer_gles3.h" #include "main/main.h" #include "os/keyboard.h" @@ -149,14 +150,49 @@ static Vector2 get_mouse_pos(NSEvent *event) { @end @interface GodotApplicationDelegate : NSObject +- (void)forceUnbundledWindowActivationHackStep1; +- (void)forceUnbundledWindowActivationHackStep2; +- (void)forceUnbundledWindowActivationHackStep3; @end @implementation GodotApplicationDelegate +- (void)forceUnbundledWindowActivationHackStep1 { + // Step1: Switch focus to macOS Dock. + // Required to perform step 2, TransformProcessType will fail if app is already the in focus. + for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) { + [app activateWithOptions:NSApplicationActivateIgnoringOtherApps]; + break; + } + [self performSelector:@selector(forceUnbundledWindowActivationHackStep2) withObject:nil afterDelay:0.02]; +} + +- (void)forceUnbundledWindowActivationHackStep2 { + // Step 2: Register app as foreground process. + ProcessSerialNumber psn = { 0, kCurrentProcess }; + (void)TransformProcessType(&psn, kProcessTransformToForegroundApplication); + + [self performSelector:@selector(forceUnbundledWindowActivationHackStep3) withObject:nil afterDelay:0.02]; +} + +- (void)forceUnbundledWindowActivationHackStep3 { + // Step 3: Switch focus back to app window. + [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)notice { + NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; + if (nsappname == nil) { + // If executable is not a bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored). + [self performSelector:@selector(forceUnbundledWindowActivationHackStep1) withObject:nil afterDelay:0.02]; + } +} + - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename { // Note: called before main loop init! char *utfs = strdup([filename UTF8String]); OS_OSX::singleton->open_with_filename.parse_utf8(utfs); + free(utfs); return YES; } @@ -228,6 +264,7 @@ static Vector2 get_mouse_pos(NSEvent *event) { NSWindow *window = (NSWindow *)[notification object]; CGFloat newBackingScaleFactor = [window backingScaleFactor]; CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue]; + [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:YES]; if (newBackingScaleFactor != oldBackingScaleFactor) { //Set new display scale and window size @@ -802,6 +839,108 @@ static int translateKey(unsigned int key) { return table[key]; } +struct _KeyCodeMap { + UniChar kchar; + int kcode; +}; + +static const _KeyCodeMap _keycodes[55] = { + { '`', KEY_QUOTELEFT }, + { '~', KEY_ASCIITILDE }, + { '0', KEY_KP_0 }, + { '1', KEY_KP_1 }, + { '2', KEY_KP_2 }, + { '3', KEY_KP_3 }, + { '4', KEY_KP_4 }, + { '5', KEY_KP_5 }, + { '6', KEY_KP_6 }, + { '7', KEY_KP_7 }, + { '8', KEY_KP_8 }, + { '9', KEY_KP_9 }, + { '-', KEY_MINUS }, + { '_', KEY_UNDERSCORE }, + { '=', KEY_EQUAL }, + { '+', KEY_PLUS }, + { 'q', KEY_Q }, + { 'w', KEY_W }, + { 'e', KEY_E }, + { 'r', KEY_R }, + { 't', KEY_T }, + { 'y', KEY_Y }, + { 'u', KEY_U }, + { 'i', KEY_I }, + { 'o', KEY_O }, + { 'p', KEY_P }, + { '[', KEY_BRACERIGHT }, + { ']', KEY_BRACELEFT }, + { '{', KEY_BRACERIGHT }, + { '}', KEY_BRACELEFT }, + { 'a', KEY_A }, + { 's', KEY_S }, + { 'd', KEY_D }, + { 'f', KEY_F }, + { 'g', KEY_G }, + { 'h', KEY_H }, + { 'j', KEY_J }, + { 'k', KEY_K }, + { 'l', KEY_L }, + { ';', KEY_SEMICOLON }, + { ':', KEY_COLON }, + { '\'', KEY_APOSTROPHE }, + { '\"', KEY_QUOTEDBL }, + { '\\', KEY_BACKSLASH }, + { '#', KEY_NUMBERSIGN }, + { 'z', KEY_Z }, + { 'x', KEY_X }, + { 'c', KEY_C }, + { 'v', KEY_V }, + { 'b', KEY_B }, + { 'n', KEY_N }, + { 'm', KEY_M }, + { ',', KEY_COMMA }, + { '.', KEY_PERIOD }, + { '/', KEY_SLASH } +}; + +static int remapKey(unsigned int key) { + + TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); + if (!currentKeyboard) + return translateKey(key); + + CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); + if (!layoutData) + return nil; + + const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData); + + UInt32 keysDown = 0; + UniChar chars[4]; + UniCharCount realLength; + + OSStatus err = UCKeyTranslate(keyboardLayout, + key, + kUCKeyActionDisplay, + 0, + LMGetKbdType(), + kUCKeyTranslateNoDeadKeysBit, + &keysDown, + sizeof(chars) / sizeof(chars[0]), + &realLength, + chars); + + if (err != noErr) { + return translateKey(key); + } + + for (unsigned int i = 0; i < 55; i++) { + if (_keycodes[i].kchar == chars[0]) { + return _keycodes[i].kcode; + } + } + return translateKey(key); +} + - (void)keyDown:(NSEvent *)event { //disable raw input in IME mode @@ -811,7 +950,7 @@ static int translateKey(unsigned int key) { ke.osx_state = [event modifierFlags]; ke.pressed = true; ke.echo = [event isARepeat]; - ke.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode])); + ke.scancode = remapKey([event keyCode]); ke.unicode = 0; push_to_key_event_buffer(ke); @@ -864,7 +1003,7 @@ static int translateKey(unsigned int key) { } ke.osx_state = mod; - ke.scancode = latin_keyboard_keycode_convert(translateKey(key)); + ke.scancode = remapKey(key); ke.unicode = 0; push_to_key_event_buffer(ke); @@ -880,7 +1019,7 @@ static int translateKey(unsigned int key) { ke.osx_state = [event modifierFlags]; ke.pressed = false; ke.echo = false; - ke.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode])); + ke.scancode = remapKey([event keyCode]); ke.unicode = 0; push_to_key_event_buffer(ke); @@ -991,15 +1130,6 @@ void OS_OSX::set_ime_position(const Point2 &p_pos) { im_position = p_pos; } -int OS_OSX::get_video_driver_count() const { - return 1; -} - -const char *OS_OSX::get_video_driver_name(int p_driver) const { - - return "GLES3"; -} - void OS_OSX::initialize_core() { crash_handler.initialize(); @@ -1092,7 +1222,7 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a unsigned int attributeCount = 0; - // OS X needs non-zero color size, so set resonable values + // OS X needs non-zero color size, so set reasonable values int colorBits = 32; // Fail if a robustness strategy was requested @@ -1111,8 +1241,12 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a ADD_ATTR(NSOpenGLPFADoubleBuffer); ADD_ATTR(NSOpenGLPFAClosestPolicy); - //we now need OpenGL 3 or better, maybe even change this to 3_3Core ? - ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); + if (p_video_driver == VIDEO_DRIVER_GLES2) { + ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy); + } else { + //we now need OpenGL 3 or better, maybe even change this to 3_3Core ? + ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); + } ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); @@ -1138,7 +1272,7 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a */ // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB - // frambuffer, so there's no need (and no way) to request it + // framebuffer, so there's no need (and no way) to request it ADD_ATTR(0); @@ -1169,13 +1303,14 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a /*** END OSX INITIALIZATION ***/ - bool use_gl2 = p_video_driver != 1; - - AudioDriverManager::add_driver(&audio_driver); - // only opengl support here... - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); + if (p_video_driver == VIDEO_DRIVER_GLES2) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + RasterizerGLES3::register_config(); + RasterizerGLES3::make_current(); + } visual_server = memnew(VisualServerRaster); if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { @@ -1372,9 +1507,7 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c Ref<Texture> texture = p_cursor; Ref<Image> image = texture->get_data(); - int image_size = 32 * 32; - - ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32); + ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256); NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL @@ -2289,6 +2422,7 @@ OS_OSX *OS_OSX::singleton = NULL; OS_OSX::OS_OSX() { + memset(cursors, 0, sizeof(cursors)); key_event_pos = 0; mouse_mode = OS::MOUSE_MODE_VISIBLE; main_loop = NULL; @@ -2325,7 +2459,7 @@ OS_OSX::OS_OSX() { NSMenuItem *menu_item; NSString *title; - NSString *nsappname = [[[NSBundle mainBundle] performSelector:@selector(localizedInfoDictionary)] objectForKey:@"CFBundleName"]; + NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; if (nsappname == nil) nsappname = [[NSProcessInfo processInfo] processName]; @@ -2396,6 +2530,8 @@ OS_OSX::OS_OSX() { [NSApp sendEvent:event]; } + + AudioDriverManager::add_driver(&audio_driver); } bool OS_OSX::_check_internal_feature_support(const String &p_feature) { diff --git a/platform/osx/platform_config.h b/platform/osx/platform_config.h index 1b497cebef..3f72831d77 100644 --- a/platform/osx/platform_config.h +++ b/platform/osx/platform_config.h @@ -31,4 +31,5 @@ #include <alloca.h> #define GLES3_INCLUDE_H "glad/glad.h" +#define GLES2_INCLUDE_H "glad/glad.h" #define PTHREAD_RENAME_SELF diff --git a/platform/server/detect.py b/platform/server/detect.py index fd4b6eae1c..7bf445b43f 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -1,4 +1,5 @@ import os +import platform import sys @@ -22,6 +23,7 @@ def get_opts(): from SCons.Variables import BoolVariable return [ BoolVariable('use_llvm', 'Use the LLVM compiler', False), + BoolVariable('use_static_cpp', 'Link libgcc and libstdc++ statically for better portability', False), ] @@ -122,6 +124,11 @@ def configure(env): if not env['builtin_libogg']: env.ParseConfig('pkg-config ogg --cflags --libs') + # On Linux wchar_t should be 32-bits + # 16-bit library shouldn't be required due to compiler optimisations + if not env['builtin_pcre2']: + env.ParseConfig('pkg-config libpcre2-32 --cflags --libs') + ## Flags # Linkflags below this line should typically stay the last ones @@ -131,4 +138,13 @@ def configure(env): env.Append(CPPPATH=['#platform/server']) env.Append(CPPFLAGS=['-DSERVER_ENABLED', '-DUNIX_ENABLED']) env.Append(LIBS=['pthread']) - env.Append(LIBS=['dl']) + + if (platform.system() == "Linux"): + env.Append(LIBS=['dl']) + + if (platform.system().find("BSD") >= 0): + env.Append(LIBS=['execinfo']) + + # Link those statically for portability + if env['use_static_cpp']: + env.Append(LINKFLAGS=['-static-libgcc', '-static-libstdc++']) diff --git a/platform/server/platform_config.h b/platform/server/platform_config.h index af4cf07393..2fa8eda337 100644 --- a/platform/server/platform_config.h +++ b/platform/server/platform_config.h @@ -28,4 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifdef __linux__ #include <alloca.h> +#endif +#if defined(__FreeBSD__) || defined(__OpenBSD__) +#include <stdlib.h> +#define PTHREAD_BSD_SET_NAME +#endif diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py index f2c5c5d42e..0e7b125dc5 100644 --- a/platform/uwp/detect.py +++ b/platform/uwp/detect.py @@ -25,8 +25,11 @@ def can_build(): def get_opts(): + from SCons.Variables import BoolVariable return [ + ('msvc_version', 'MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.', None), + BoolVariable('use_mingw', 'Use the Mingw compiler, even if MSVC is installed. Only used on Windows.', False), ] @@ -40,6 +43,8 @@ def get_flags(): def configure(env): + env.msvc = True + if (env["bits"] != "default"): print("Error: bits argument is disabled for MSVC") print(""" diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 620f6c0f24..7d7bee9227 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -1082,7 +1082,7 @@ public: r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), "")); - // Capabilites + // Capabilities const char **basic = uwp_capabilities; while (*basic) { r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/" + String(*basic).camelcase_to_underscore(false)), false)); diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp index 8b57fdd9ce..d312fbcb12 100644 --- a/platform/windows/context_gl_win.cpp +++ b/platform/windows/context_gl_win.cpp @@ -38,6 +38,8 @@ #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 #define WGL_CONTEXT_FLAGS_ARB 0x2094 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int *); @@ -153,6 +155,7 @@ Error ContextGL_Win::initialize() { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, //we want a 3.3 context WGL_CONTEXT_MINOR_VERSION_ARB, 3, //and it shall be forward compatible so that we can only use up to date functionality + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /*| _WGL_CONTEXT_DEBUG_BIT_ARB*/, 0 }; //zero indicates the end of the array diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 94a3efcd89..2ce55d98be 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -12,23 +12,17 @@ def get_name(): def can_build(): - if (os.name == "nt"): # Building natively on Windows - if (os.getenv("VCINSTALLDIR")): # MSVC + # If VCINSTALLDIR is set in the OS environ, use traditional Godot logic to set up MSVC + if (os.getenv("VCINSTALLDIR")): # MSVC, manual setup return True - print("MSVC not detected (no VCINSTALLDIR environment variable), attempting MinGW.") - mingw32 = "" - mingw64 = "" - if (os.getenv("MINGW32_PREFIX")): - mingw32 = os.getenv("MINGW32_PREFIX") - if (os.getenv("MINGW64_PREFIX")): - mingw64 = os.getenv("MINGW64_PREFIX") - - test = "gcc --version > NUL 2>&1" - if (os.system(test) == 0 or os.system(mingw32 + test) == 0 or os.system(mingw64 + test) == 0): - return True + # Otherwise, let SCons find MSVC if installed, or else Mingw. + # Since we're just returning True here, if there's no compiler + # installed, we'll get errors when it tries to build with the + # null compiler. + return True if (os.name == "posix"): # Cross-compiling with MinGW-w64 (old MinGW32 is not supported) @@ -70,6 +64,8 @@ def get_opts(): ('target_win_version', 'Targeted Windows version, >= 0x0601 (Windows 7)', '0x0601'), EnumVariable('debug_symbols', 'Add debug symbols to release version', 'yes', ('yes', 'no', 'full')), BoolVariable('separate_debug_symbols', 'Create a separate file with the debug symbols', False), + ('msvc_version', 'MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.', None), + BoolVariable('use_mingw', 'Use the Mingw compiler, even if MSVC is installed. Only used on Windows.', False), ] @@ -98,192 +94,253 @@ def build_res_file(target, source, env): return 0 -def configure(env): - - env.Append(CPPPATH=['#platform/windows']) - - if (os.name == "nt" and os.getenv("VCINSTALLDIR")): # MSVC +def setup_msvc_manual(env): + """Set up env to use MSVC manually, using VCINSTALLDIR""" + if (env["bits"] != "default"): + print(""" + Bits argument is not supported for MSVC compilation. Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console + (or Visual Studio settings) that is being used to run SCons. As a consequence, bits argument is disabled. Run scons again without bits + argument (example: scons p=windows) and SCons will attempt to detect what MSVC compiler will be executed and inform you. + """) + raise SCons.Errors.UserError("Bits argument should not be used when using VCINSTALLDIR") + + # Force bits arg + # (Actually msys2 mingw can support 64-bit, we could detect that) + env["bits"] = "32" + env["x86_libtheora_opt_vc"] = True + + # find compiler manually + compiler_version_str = methods.detect_visual_c_compiler_version(env['ENV']) + print("Found MSVC compiler: " + compiler_version_str) + + # If building for 64bit architecture, disable assembly optimisations for 32 bit builds (theora as of writing)... vc compiler for 64bit can not compile _asm + if(compiler_version_str == "amd64" or compiler_version_str == "x86_amd64"): + env["bits"] = "64" + env["x86_libtheora_opt_vc"] = False + print("Compiled program architecture will be a 64 bit executable (forcing bits=64).") + elif (compiler_version_str == "x86" or compiler_version_str == "amd64_x86"): + print("Compiled program architecture will be a 32 bit executable. (forcing bits=32).") + else: + print("Failed to manually detect MSVC compiler architecture version... Defaulting to 32bit executable settings (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this build is compiled for. You should check your settings/compilation setup, or avoid setting VCINSTALLDIR.") + +def setup_msvc_auto(env): + """Set up MSVC using SCons's auto-detection logic""" + + # If MSVC_VERSION is set by SCons, we know MSVC is installed. + # But we may want a different version or target arch. + + # The env may have already been set up with default MSVC tools, so + # reset a few things so we can set it up with the tools we want. + # (Ideally we'd decide on the tool config before configuring any + # environment, and just set the env up once, but this function runs + # on an existing env so this is the simplest way.) + env['MSVC_SETUP_RUN'] = False # Need to set this to re-run the tool + env['MSVS_VERSION'] = None + env['MSVC_VERSION'] = None + env['TARGET_ARCH'] = None + if env['bits'] != 'default': + env['TARGET_ARCH'] = {'32': 'x86', '64': 'x86_64'}[env['bits']] + if env.has_key('msvc_version'): + env['MSVC_VERSION'] = env['msvc_version'] + env.Tool('msvc') + env.Tool('mssdk') # we want the MS SDK + # Note: actual compiler version can be found in env['MSVC_VERSION'], e.g. "14.1" for VS2015 + # Get actual target arch into bits (it may be "default" at this point): + if env['TARGET_ARCH'] in ('amd64', 'x86_64'): + env['bits'] = 64 + else: + env['bits'] = 32 + print(" Found MSVC version %s, arch %s, bits=%s" % (env['MSVC_VERSION'], env['TARGET_ARCH'], env['bits'])) + if env['TARGET_ARCH'] in ('amd64', 'x86_64'): + env["x86_libtheora_opt_vc"] = False + +def setup_mingw(env): + """Set up env for use with mingw""" + # Nothing to do here + print("Using Mingw") + pass + +def configure_msvc(env, manual_msvc_config): + """Configure env to work with MSVC""" + + # Build type + + if (env["target"] == "release"): + env.Append(CCFLAGS=['/O2']) + env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS']) + env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup']) + + elif (env["target"] == "release_debug"): + env.Append(CCFLAGS=['/O2']) + env.AppendUnique(CPPDEFINES = ['DEBUG_ENABLED']) + env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) + + elif (env["target"] == "debug_release"): + env.Append(CCFLAGS=['/Z7', '/Od']) + env.Append(LINKFLAGS=['/DEBUG']) + env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS']) + env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup']) + + elif (env["target"] == "debug"): + env.AppendUnique(CCFLAGS=['/Z7', '/Od', '/EHsc']) + env.AppendUnique(CPPDEFINES = ['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED', + 'D3D_DEBUG_INFO']) + env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) + env.Append(LINKFLAGS=['/DEBUG']) + + ## Compile/link flags + + env.AppendUnique(CCFLAGS=['/MT', '/Gd', '/GR', '/nologo']) + env.AppendUnique(CXXFLAGS=['/TP']) # assume all sources are C++ + if manual_msvc_config: # should be automatic if SCons found it + env.Append(CPPPATH=[os.getenv("WindowsSdkDir") + "/Include"]) + + env.AppendUnique(CPPDEFINES = ['WINDOWS_ENABLED', 'OPENGL_ENABLED', + 'RTAUDIO_ENABLED', 'WASAPI_ENABLED', + 'TYPED_METHOD_BIND', 'WIN32', 'MSVC', + {'WINVER' : '$target_win_version', + '_WIN32_WINNT': '$target_win_version'}]) + if env["bits"] == "64": + env.AppendUnique(CPPDEFINES=['_WIN64']) + + ## Libs + + LIBS = ['winmm', 'opengl32', 'dsound', 'kernel32', 'ole32', 'oleaut32', + 'user32', 'gdi32', 'IPHLPAPI', 'Shlwapi', 'wsock32', 'Ws2_32', + 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt'] + env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS]) + + if manual_msvc_config: + env.Append(LIBPATH=[os.getenv("WindowsSdkDir") + "/Lib"]) - env['ENV']['TMP'] = os.environ['TMP'] + ## LTO - ## Build type - - if (env["target"] == "release"): - env.Append(CCFLAGS=['/O2']) - env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS']) - env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup']) - - elif (env["target"] == "release_debug"): - env.Append(CCFLAGS=['/O2', '/DDEBUG_ENABLED']) - env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) - - elif (env["target"] == "debug_release"): - env.Append(CCFLAGS=['/Z7', '/Od']) - env.Append(LINKFLAGS=['/DEBUG']) - env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS']) - env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup']) - - elif (env["target"] == "debug"): - env.Append(CCFLAGS=['/Z7', '/DDEBUG_ENABLED', '/DDEBUG_MEMORY_ENABLED', '/DD3D_DEBUG_INFO', '/Od', '/EHsc']) - env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) - env.Append(LINKFLAGS=['/DEBUG']) - - ## Architecture - - # Note: this detection/override code from here onward should be here instead of in SConstruct because it's platform and compiler specific (MSVC/Windows) - if (env["bits"] != "default"): - print("Error: bits argument is disabled for MSVC") - print(""" - Bits argument is not supported for MSVC compilation. Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console - (or Visual Studio settings) that is being used to run SCons. As a consequence, bits argument is disabled. Run scons again without bits - argument (example: scons p=windows) and SCons will attempt to detect what MSVC compiler will be executed and inform you. - """) - sys.exit() - - # Forcing bits argument because MSVC does not have a flag to set this through SCons... it's different compilers (cl.exe's) called from the proper command prompt - # that decide the architecture that is build for. Scons can only detect the os.getenviron (because vsvarsall.bat sets a lot of stuff for cl.exe to work with) - env["bits"] = "32" - env["x86_libtheora_opt_vc"] = True - - ## Compiler configuration - - env['ENV'] = os.environ - # This detection function needs the tools env (that is env['ENV'], not SCons's env), and that is why it's this far bellow in the code - compiler_version_str = methods.detect_visual_c_compiler_version(env['ENV']) - - print("Detected MSVC compiler: " + compiler_version_str) - # If building for 64bit architecture, disable assembly optimisations for 32 bit builds (theora as of writting)... vc compiler for 64bit can not compile _asm - if(compiler_version_str == "amd64" or compiler_version_str == "x86_amd64"): - env["bits"] = "64" - env["x86_libtheora_opt_vc"] = False - print("Compiled program architecture will be a 64 bit executable (forcing bits=64).") - elif (compiler_version_str == "x86" or compiler_version_str == "amd64_x86"): - print("Compiled program architecture will be a 32 bit executable. (forcing bits=32).") + if (env["use_lto"]): + env.AppendUnique(CCFLAGS=['/GL']) + env.AppendUnique(ARFLAGS=['/LTCG']) + if env["progress"]: + env.AppendUnique(LINKFLAGS=['/LTCG:STATUS']) else: - print("Failed to detect MSVC compiler architecture version... Defaulting to 32bit executable settings (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this build is compiled for. You should check your settings/compilation setup.") + env.AppendUnique(LINKFLAGS=['/LTCG']) - ## Compile flags + if manual_msvc_config: + env.Append(CPPPATH=[p for p in os.getenv("INCLUDE").split(";")]) + env.Append(LIBPATH=[p for p in os.getenv("LIB").split(";")]) - env.Append(CCFLAGS=['/MT', '/Gd', '/GR', '/nologo']) - env.Append(CXXFLAGS=['/TP']) - env.Append(CPPFLAGS=['/DMSVC', '/GR', ]) - env.Append(CCFLAGS=['/I' + os.getenv("WindowsSdkDir") + "/Include"]) + # Incremental linking fix + env['BUILDERS']['ProgramOriginal'] = env['BUILDERS']['Program'] + env['BUILDERS']['Program'] = methods.precious_program - env.Append(CCFLAGS=['/DWINDOWS_ENABLED']) - env.Append(CCFLAGS=['/DOPENGL_ENABLED']) - env.Append(CCFLAGS=['/DRTAUDIO_ENABLED']) - env.Append(CCFLAGS=['/DWASAPI_ENABLED']) - env.Append(CCFLAGS=['/DTYPED_METHOD_BIND']) - env.Append(CCFLAGS=['/DWIN32']) - env.Append(CCFLAGS=['/DWINVER=%s' % env['target_win_version'], '/D_WIN32_WINNT=%s' % env['target_win_version']]) - if env["bits"] == "64": - env.Append(CCFLAGS=['/D_WIN64']) +def configure_mingw(env): + # Workaround for MinGW. See: + # http://www.scons.org/wiki/LongCmdLinesOnWin32 + env.use_windows_spawn_fix() - LIBS = ['winmm', 'opengl32', 'dsound', 'kernel32', 'ole32', 'oleaut32', 'user32', 'gdi32', 'IPHLPAPI', 'Shlwapi', 'wsock32', 'Ws2_32', 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt'] - env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS]) + ## Build type - env.Append(LIBPATH=[os.getenv("WindowsSdkDir") + "/Lib"]) + if (env["target"] == "release"): + env.Append(CCFLAGS=['-msse2']) - if (os.getenv("VCINSTALLDIR")): - VC_PATH = os.getenv("VCINSTALLDIR") + if (env["bits"] == "64"): + env.Append(CCFLAGS=['-O3']) else: - VC_PATH = "" + env.Append(CCFLAGS=['-O2']) - if (env["use_lto"]): - env.Append(CCFLAGS=['/GL']) - env.Append(ARFLAGS=['/LTCG']) - if env["progress"]: - env.Append(LINKFLAGS=['/LTCG:STATUS']) - else: - env.Append(LINKFLAGS=['/LTCG']) + env.Append(LINKFLAGS=['-Wl,--subsystem,windows']) - env.Append(CCFLAGS=["/I" + p for p in os.getenv("INCLUDE").split(";")]) - env.Append(LIBPATH=[p for p in os.getenv("LIB").split(";")]) + if (env["debug_symbols"] == "yes"): + env.Prepend(CCFLAGS=['-g1']) + if (env["debug_symbols"] == "full"): + env.Prepend(CCFLAGS=['-g2']) - # Incremental linking fix - env['BUILDERS']['ProgramOriginal'] = env['BUILDERS']['Program'] - env['BUILDERS']['Program'] = methods.precious_program + elif (env["target"] == "release_debug"): + env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED']) + if (env["debug_symbols"] == "yes"): + env.Prepend(CCFLAGS=['-g1']) + if (env["debug_symbols"] == "full"): + env.Prepend(CCFLAGS=['-g2']) - else: # MinGW - - # Workaround for MinGW. See: - # http://www.scons.org/wiki/LongCmdLinesOnWin32 - env.use_windows_spawn_fix() - - ## Build type + elif (env["target"] == "debug"): + env.Append(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) - if (env["target"] == "release"): - env.Append(CCFLAGS=['-msse2']) + ## Compiler configuration - if (env["bits"] == "64"): - env.Append(CCFLAGS=['-O3']) - else: - env.Append(CCFLAGS=['-O2']) + if (os.name == "nt"): + env['ENV']['TMP'] = os.environ['TMP'] # way to go scons, you can be so stupid sometimes + else: + env["PROGSUFFIX"] = env["PROGSUFFIX"] + ".exe" # for linux cross-compilation - env.Append(LINKFLAGS=['-Wl,--subsystem,windows']) + if (env["bits"] == "default"): + if (os.name == "nt"): + env["bits"] = "64" if "PROGRAMFILES(X86)" in os.environ else "32" + else: # default to 64-bit on Linux + env["bits"] = "64" - if (env["debug_symbols"] == "yes"): - env.Prepend(CCFLAGS=['-g1']) - if (env["debug_symbols"] == "full"): - env.Prepend(CCFLAGS=['-g2']) + mingw_prefix = "" - elif (env["target"] == "release_debug"): - env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED']) - if (env["debug_symbols"] == "yes"): - env.Prepend(CCFLAGS=['-g1']) - if (env["debug_symbols"] == "full"): - env.Prepend(CCFLAGS=['-g2']) + if (env["bits"] == "32"): + env.Append(LINKFLAGS=['-static']) + env.Append(LINKFLAGS=['-static-libgcc']) + env.Append(LINKFLAGS=['-static-libstdc++']) + mingw_prefix = env["mingw_prefix_32"] + else: + env.Append(LINKFLAGS=['-static']) + mingw_prefix = env["mingw_prefix_64"] - elif (env["target"] == "debug"): - env.Append(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env["CC"] = mingw_prefix + "gcc" + env['AS'] = mingw_prefix + "as" + env['CXX'] = mingw_prefix + "g++" + env['AR'] = mingw_prefix + "gcc-ar" + env['RANLIB'] = mingw_prefix + "gcc-ranlib" + env['LINK'] = mingw_prefix + "g++" + env["x86_libtheora_opt_gcc"] = True - ## Compiler configuration + if env['use_lto']: + env.Append(CCFLAGS=['-flto']) + env.Append(LINKFLAGS=['-flto=' + str(env.GetOption("num_jobs"))]) - if (os.name == "nt"): - env['ENV']['TMP'] = os.environ['TMP'] # way to go scons, you can be so stupid sometimes - else: - env["PROGSUFFIX"] = env["PROGSUFFIX"] + ".exe" # for linux cross-compilation - if (env["bits"] == "default"): - if (os.name == "nt"): - env["bits"] = "64" if "PROGRAMFILES(X86)" in os.environ else "32" - else: # default to 64-bit on Linux - env["bits"] = "64" + ## Compile flags - mingw_prefix = "" + env.Append(CCFLAGS=['-DWINDOWS_ENABLED', '-mwindows']) + env.Append(CCFLAGS=['-DOPENGL_ENABLED']) + env.Append(CCFLAGS=['-DRTAUDIO_ENABLED']) + env.Append(CCFLAGS=['-DWASAPI_ENABLED']) + env.Append(CCFLAGS=['-DWINVER=%s' % env['target_win_version'], '-D_WIN32_WINNT=%s' % env['target_win_version']]) + env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt']) - if (env["bits"] == "32"): - env.Append(LINKFLAGS=['-static']) - env.Append(LINKFLAGS=['-static-libgcc']) - env.Append(LINKFLAGS=['-static-libstdc++']) - mingw_prefix = env["mingw_prefix_32"] - else: - env.Append(LINKFLAGS=['-static']) - mingw_prefix = env["mingw_prefix_64"] + env.Append(CPPFLAGS=['-DMINGW_ENABLED']) - env["CC"] = mingw_prefix + "gcc" - env['AS'] = mingw_prefix + "as" - env['CXX'] = mingw_prefix + "g++" - env['AR'] = mingw_prefix + "gcc-ar" - env['RANLIB'] = mingw_prefix + "gcc-ranlib" - env['LINK'] = mingw_prefix + "g++" - env["x86_libtheora_opt_gcc"] = True + # resrc + env.Append(BUILDERS={'RES': env.Builder(action=build_res_file, suffix='.o', src_suffix='.rc')}) - if env['use_lto']: - env.Append(CCFLAGS=['-flto']) - env.Append(LINKFLAGS=['-flto=' + str(env.GetOption("num_jobs"))]) +def configure(env): + # At this point the env has been set up with basic tools/compilers. + env.Append(CPPPATH=['#platform/windows']) + print("Configuring for Windows: target=%s, bits=%s" % (env['target'], env['bits'])) - ## Compile flags + if (os.name == "nt"): + env['ENV'] = os.environ # this makes build less repeatable, but simplifies some things + env['ENV']['TMP'] = os.environ['TMP'] - env.Append(CCFLAGS=['-DWINDOWS_ENABLED', '-mwindows']) - env.Append(CCFLAGS=['-DOPENGL_ENABLED']) - env.Append(CCFLAGS=['-DRTAUDIO_ENABLED']) - env.Append(CCFLAGS=['-DWASAPI_ENABLED']) - env.Append(CCFLAGS=['-DWINVER=%s' % env['target_win_version'], '-D_WIN32_WINNT=%s' % env['target_win_version']]) - env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt']) + # First figure out which compiler, version, and target arch we're using + if os.getenv("VCINSTALLDIR"): + # Manual setup of MSVC + setup_msvc_manual(env) + env.msvc = True + manual_msvc_config = True + elif env.get('MSVC_VERSION', ''): + setup_msvc_auto(env) + env.msvc = True + manual_msvc_config = False + else: + setup_mingw(env) + env.msvc = False - env.Append(CPPFLAGS=['-DMINGW_ENABLED']) + # Now set compiler/linker flags + if env.msvc: + configure_msvc(env, manual_msvc_config) - # resrc - env.Append(BUILDERS={'RES': env.Builder(action=build_res_file, suffix='.o', src_suffix='.rc')}) + else: # MinGW + configure_mingw(env) diff --git a/platform/windows/godot_res.rc b/platform/windows/godot_res.rc index c535a749c0..f2dca10d55 100644 --- a/platform/windows/godot_res.rc +++ b/platform/windows/godot_res.rc @@ -3,11 +3,9 @@ #define _STR(m_x) #m_x #define _MKSTR(m_x) _STR(m_x) #endif + #ifndef VERSION_PATCH #define VERSION_PATCH 0 -#define PATCH_STRING -#else -#define PATCH_STRING "." _MKSTR(VERSION_PATCH) #endif GODOT_ICON ICON platform/windows/godot.ico @@ -24,12 +22,12 @@ BEGIN BEGIN VALUE "CompanyName", "Godot Engine" VALUE "FileDescription", VERSION_NAME " Editor" - VALUE "FileVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_PATCH) + VALUE "FileVersion", VERSION_NUMBER VALUE "ProductName", VERSION_NAME VALUE "Licence", "MIT" - VALUE "LegalCopyright", "Copyright (c) 2007-" _MKSTR(VERSION_YEAR) " Juan Linietsky, Ariel Manzur" + VALUE "LegalCopyright", "Copyright (c) 2007-" _MKSTR(VERSION_YEAR) " Juan Linietsky, Ariel Manzur and contributors" VALUE "Info", "https://godotengine.org" - VALUE "ProductVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) PATCH_STRING "." VERSION_BUILD + VALUE "ProductVersion", VERSION_FULL_BUILD END END BLOCK "VarFileInfo" diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 20129299a1..f51d969c16 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -30,6 +30,7 @@ #include "os_windows.h" +#include "drivers/gles2/rasterizer_gles2.h" #include "drivers/gles3/rasterizer_gles3.h" #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" @@ -151,26 +152,6 @@ void RedirectIOToConsole() { // point to console as well } -int OS_Windows::get_video_driver_count() const { - - return 1; -} -const char *OS_Windows::get_video_driver_name(int p_driver) const { - - return "GLES3"; -} - -int OS_Windows::get_audio_driver_count() const { - - return AudioDriverManager::get_driver_count(); -} -const char *OS_Windows::get_audio_driver_name(int p_driver) const { - - AudioDriver *driver = AudioDriverManager::get_driver(p_driver); - ERR_FAIL_COND_V(!driver, ""); - return AudioDriverManager::get_driver(p_driver)->get_name(); -} - void OS_Windows::initialize_core() { crash_handler.initialize(); @@ -632,7 +613,16 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) video_mode.width = window_w; video_mode.height = window_h; } - //return 0; // Jump Back + if (wParam == SIZE_MAXIMIZED) { + maximized = true; + minimized = false; + } else if (wParam == SIZE_MINIMIZED) { + maximized = false; + minimized = true; + } else if (wParam == SIZE_RESTORED) { + maximized = false; + minimized = false; + } } break; case WM_ENTERSIZEMOVE: { @@ -1080,12 +1070,19 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int } #if defined(OPENGL_ENABLED) - gl_context = memnew(ContextGL_Win(hWnd, true)); - gl_context->initialize(); + if (p_video_driver == VIDEO_DRIVER_GLES2) { + gl_context = memnew(ContextGL_Win(hWnd, false)); + gl_context->initialize(); - RasterizerGLES3::register_config(); + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + gl_context = memnew(ContextGL_Win(hWnd, true)); + gl_context->initialize(); - RasterizerGLES3::make_current(); + RasterizerGLES3::register_config(); + RasterizerGLES3::make_current(); + } gl_context->set_use_vsync(video_mode.use_vsync); #endif @@ -1899,26 +1896,25 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap Ref<Texture> texture = p_cursor; Ref<Image> image = texture->get_data(); - UINT image_size = 32 * 32; + UINT image_size = texture->get_width() * texture->get_height(); UINT size = sizeof(UINT) * image_size; - ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32); + ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256); // Create the BITMAP with alpha channel COLORREF *buffer = (COLORREF *)malloc(sizeof(COLORREF) * image_size); image->lock(); for (UINT index = 0; index < image_size; index++) { - int column_index = floor(index / 32); - int row_index = index % 32; + int row_index = floor(index / texture->get_width()); + int column_index = index % texture->get_width(); - Color pcColor = image->get_pixel(row_index, column_index); - *(buffer + index) = image->get_pixel(row_index, column_index).to_argb32(); + *(buffer + index) = image->get_pixel(column_index, row_index).to_argb32(); } image->unlock(); // Using 4 channels, so 4 * 8 bits - HBITMAP bitmap = CreateBitmap(32, 32, 1, 4 * 8, buffer); + HBITMAP bitmap = CreateBitmap(texture->get_width(), texture->get_height(), 1, 4 * 8, buffer); COLORREF clrTransparent = -1; // Create the AND and XOR masks for the bitmap diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 4c4fbcf8f0..3d13627bfa 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -142,12 +142,6 @@ class OS_Windows : public OS { // functions used by main to initialize/deintialize the OS protected: - virtual int get_video_driver_count() const; - virtual const char *get_video_driver_name(int p_driver) const; - - virtual int get_audio_driver_count() const; - virtual const char *get_audio_driver_name(int p_driver) const; - virtual void initialize_core(); virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h index 10ec9110d1..d100385e80 100644 --- a/platform/windows/platform_config.h +++ b/platform/windows/platform_config.h @@ -33,3 +33,4 @@ //#include <alloca.h> //#endif #define GLES3_INCLUDE_H "glad/glad.h" +#define GLES2_INCLUDE_H "glad/glad.h" diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index 20f2212861..1a7cbc0d6d 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -146,20 +146,39 @@ Error ContextGL_X11::initialize() { int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler); - if (!opengl_3_context) { - //oldstyle context: - p->glx_context = glXCreateContext(x11_display, vi, 0, GL_TRUE); - } else { - static int context_attribs[] = { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 3, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /*|GLX_CONTEXT_DEBUG_BIT_ARB*/, - None - }; - - p->glx_context = glXCreateContextAttribsARB(x11_display, fbc[0], NULL, true, context_attribs); - ERR_EXPLAIN("Could not obtain an OpenGL 3.3 context!"); - ERR_FAIL_COND_V(ctxErrorOccurred || !p->glx_context, ERR_UNCONFIGURED); + switch (context_type) { + case GLES_2_0_COMPATIBLE: + case OLDSTYLE: { + p->glx_context = glXCreateContext(x11_display, vi, 0, GL_TRUE); + } break; + /* + case ContextType::GLES_2_0_COMPATIBLE: { + + static int context_attribs[] = { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 0, + None + }; + + p->glx_context = glXCreateContextAttribsARB(x11_display, fbc[0], NULL, true, context_attribs); + ERR_EXPLAIN("Could not obtain an OpenGL 3.0 context!"); + ERR_FAIL_COND_V(!p->glx_context, ERR_UNCONFIGURED); + } break; + */ + case GLES_3_0_COMPATIBLE: { + + static int context_attribs[] = { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 3, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /*|GLX_CONTEXT_DEBUG_BIT_ARB*/, + None + }; + + p->glx_context = glXCreateContextAttribsARB(x11_display, fbc[0], NULL, true, context_attribs); + ERR_EXPLAIN("Could not obtain an OpenGL 3.3 context!"); + ERR_FAIL_COND_V(ctxErrorOccurred || !p->glx_context, ERR_UNCONFIGURED); + } break; } XSync(x11_display, False); @@ -229,13 +248,13 @@ bool ContextGL_X11::is_using_vsync() const { return use_vsync; } -ContextGL_X11::ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, bool p_opengl_3_context) : +ContextGL_X11::ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, ContextType p_context_type) : x11_window(p_x11_window) { default_video_mode = p_default_video_mode; x11_display = p_x11_display; - opengl_3_context = p_opengl_3_context; + context_type = p_context_type; double_buffer = false; direct_render = false; diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h index c969f0044d..b54cc84fac 100644 --- a/platform/x11/context_gl_x11.h +++ b/platform/x11/context_gl_x11.h @@ -46,6 +46,14 @@ struct ContextGL_X11_Private; class ContextGL_X11 : public ContextGL { +public: + enum ContextType { + OLDSTYLE, + GLES_2_0_COMPATIBLE, + GLES_3_0_COMPATIBLE + }; + +private: ContextGL_X11_Private *p; OS::VideoMode default_video_mode; //::Colormap x11_colormap; @@ -54,8 +62,8 @@ class ContextGL_X11 : public ContextGL { bool double_buffer; bool direct_render; int glx_minor, glx_major; - bool opengl_3_context; bool use_vsync; + ContextType context_type; public: virtual void release_current(); @@ -69,7 +77,7 @@ public: virtual void set_use_vsync(bool p_use); virtual bool is_using_vsync() const; - ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, bool p_opengl_3_context); + ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, ContextType p_context_type); ~ContextGL_X11(); }; diff --git a/platform/x11/crash_handler_x11.cpp b/platform/x11/crash_handler_x11.cpp index 43b9051ea7..d39fc33f81 100644 --- a/platform/x11/crash_handler_x11.cpp +++ b/platform/x11/crash_handler_x11.cpp @@ -32,8 +32,9 @@ #define CRASH_HANDLER_ENABLED 1 #endif +#include "crash_handler_x11.h" #include "main/main.h" -#include "os_x11.h" +#include "os/os.h" #include "project_settings.h" #ifdef CRASH_HANDLER_ENABLED diff --git a/platform/x11/detect.py b/platform/x11/detect.py index da2b0701b6..5820a926e9 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -234,10 +234,10 @@ def configure(env): print("ALSA libraries not found, disabling driver") if env['pulseaudio']: - if (os.system("pkg-config --exists libpulse-simple") == 0): # 0 means found + if (os.system("pkg-config --exists libpulse") == 0): # 0 means found print("Enabling PulseAudio") env.Append(CPPFLAGS=["-DPULSEAUDIO_ENABLED"]) - env.ParseConfig('pkg-config --cflags --libs libpulse-simple') + env.ParseConfig('pkg-config --cflags --libs libpulse') else: print("PulseAudio development libraries not found, disabling driver") diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 2027667af3..338d13410f 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "os_x11.h" +#include "drivers/gles2/rasterizer_gles2.h" #include "drivers/gles3/rasterizer_gles3.h" #include "errno.h" #include "key_mapping_x11.h" @@ -76,25 +77,6 @@ #include <X11/XKBlib.h> -int OS_X11::get_video_driver_count() const { - return 1; -} - -const char *OS_X11::get_video_driver_name(int p_driver) const { - return "GLES3"; -} - -int OS_X11::get_audio_driver_count() const { - return AudioDriverManager::get_driver_count(); -} - -const char *OS_X11::get_audio_driver_name(int p_driver) const { - - AudioDriver *driver = AudioDriverManager::get_driver(p_driver); - ERR_FAIL_COND_V(!driver, ""); - return AudioDriverManager::get_driver(p_driver)->get_name(); -} - void OS_X11::initialize_core() { crash_handler.initialize(); @@ -283,12 +265,25 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a //print_line("def videomode "+itos(current_videomode.width)+","+itos(current_videomode.height)); #if defined(OPENGL_ENABLED) - context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, true)); - context_gl->initialize(); + ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_3_0_COMPATIBLE; + + if (p_video_driver == VIDEO_DRIVER_GLES2) { + opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE; + } - RasterizerGLES3::register_config(); + context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type)); + context_gl->initialize(); - RasterizerGLES3::make_current(); + switch (opengl_api_type) { + case ContextGL_X11::GLES_2_0_COMPATIBLE: { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } break; + case ContextGL_X11::GLES_3_0_COMPATIBLE: { + RasterizerGLES3::register_config(); + RasterizerGLES3::make_current(); + } break; + } context_gl->set_use_vsync(current_videomode.use_vsync); @@ -751,7 +746,7 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { XFree(xsh); } - // Using EWMH -- Extened Window Manager Hints + // Using EWMH -- Extended Window Manager Hints XEvent xev; Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); Atom wm_fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False); @@ -1193,6 +1188,7 @@ bool OS_X11::is_window_maximized() const { unsigned long len; unsigned long remaining; unsigned char *data = NULL; + bool retval = false; int result = XGetWindowProperty( x11_display, @@ -1221,13 +1217,15 @@ bool OS_X11::is_window_maximized() const { if (atoms[i] == wm_max_vert) found_wm_max_vert = true; - if (found_wm_max_horz && found_wm_max_vert) - return true; + if (found_wm_max_horz && found_wm_max_vert) { + retval = true; + break; + } } - XFree(atoms); } - return false; + XFree(data); + return retval; } void OS_X11::set_window_always_on_top(bool p_enabled) { @@ -2377,11 +2375,11 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c Ref<Texture> texture = p_cursor; Ref<Image> image = texture->get_data(); - ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32); + ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256); // Create the cursor structure XcursorImage *cursor_image = XcursorImageCreate(texture->get_width(), texture->get_height()); - XcursorUInt image_size = 32 * 32; + XcursorUInt image_size = texture->get_width() * texture->get_height(); XcursorDim size = sizeof(XcursorPixel) * image_size; cursor_image->version = 1; @@ -2395,10 +2393,10 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c image->lock(); for (XcursorPixel index = 0; index < image_size; index++) { - int column_index = floor(index / 32); - int row_index = index % 32; + int row_index = floor(index / texture->get_width()); + int column_index = index % texture->get_width(); - *(cursor_image->pixels + index) = image->get_pixel(row_index, column_index).to_argb32(); + *(cursor_image->pixels + index) = image->get_pixel(column_index, row_index).to_argb32(); } image->unlock(); diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 494845bc56..610dba0716 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -188,12 +188,6 @@ class OS_X11 : public OS_Unix { Bool xrandr_ext_ok; protected: - virtual int get_video_driver_count() const; - virtual const char *get_video_driver_name(int p_driver) const; - - virtual int get_audio_driver_count() const; - virtual const char *get_audio_driver_name(int p_driver) const; - virtual void initialize_core(); virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void finalize(); diff --git a/platform/x11/platform_config.h b/platform/x11/platform_config.h index 58d6b210ee..b757be49c3 100644 --- a/platform/x11/platform_config.h +++ b/platform/x11/platform_config.h @@ -37,3 +37,4 @@ #endif #define GLES3_INCLUDE_H "glad/glad.h" +#define GLES2_INCLUDE_H "glad/glad.h" diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index fc67d28a29..f998f23d3b 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -226,14 +226,14 @@ void AudioStreamPlayer2D::_notification(int p_what) { setseek = setplay; active = true; setplay = -1; - //do not update, this makes it easier to animate (will shut off otherise) + //do not update, this makes it easier to animate (will shut off otherwise) //_change_notify("playing"); //update property in editor } //stop playing if no longer active if (!active) { set_physics_process_internal(false); - //do not update, this makes it easier to animate (will shut off otherise) + //do not update, this makes it easier to animate (will shut off otherwise) //_change_notify("playing"); //update property in editor emit_signal("finished"); } diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 8d7fce8cc4..5cca5705a0 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -779,13 +779,13 @@ void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Colo VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid, rid_normal, p_antialiased); } -void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, RID p_skeleton) { +void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map) { ERR_FAIL_COND(p_mesh.is_null()); RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), texture_rid, normal_map_rid, p_skeleton); + VisualServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), texture_rid, normal_map_rid); } void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map) { @@ -1032,7 +1032,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture", "normal_map", "antialiased"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_string", "font", "position", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1)), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("draw_char", "font", "position", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1))); - ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map", "skeleton"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>()), DEFVAL(RID())); + ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>())); ClassDB::bind_method(D_METHOD("draw_multimesh", "mesh", "texture", "normal_map"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>())); ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index d0bf584b38..980fcb4109 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -283,7 +283,7 @@ public: void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false); void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false); - void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, RID p_skeleton); + void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map); void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map); void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1); diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 978fb379ac..7e2026d225 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -175,7 +175,8 @@ void CollisionPolygon2D::_notification(int p_what) { Vector2 p = polygon[i]; Vector2 n = polygon[(i + 1) % polygon.size()]; - draw_line(p, n, Color(0.9, 0.2, 0.0, 0.8), 3); + // draw line with width <= 1, so it does not scale with zoom and break pixel exact editing + draw_line(p, n, Color(0.9, 0.2, 0.0, 0.8), 1); } #define DEBUG_DECOMPOSE #if defined(TOOLS_ENABLED) && defined(DEBUG_DECOMPOSE) diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index f0ab9652b4..ba4a5c5571 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -252,12 +252,15 @@ void Line2D::_draw() { lb.sharp_limit = _sharp_limit; lb.width = _width; - lb.build(); - RID texture_rid; - if (_texture.is_valid()) + if (_texture.is_valid()) { texture_rid = (**_texture).get_rid(); + lb.tile_aspect = _texture->get_size().aspect(); + } + + lb.build(); + VS::get_singleton()->canvas_item_add_triangle_array( get_canvas_item(), lb.indices, diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp index b1a072729f..845788bada 100644 --- a/scene/2d/line_builder.cpp +++ b/scene/2d/line_builder.cpp @@ -101,6 +101,7 @@ LineBuilder::LineBuilder() { round_precision = 8; begin_cap_mode = Line2D::LINE_CAP_NONE; end_cap_mode = Line2D::LINE_CAP_NONE; + tile_aspect = 1.f; _interpolate_color = false; _last_index[0] = 0; @@ -111,6 +112,7 @@ void LineBuilder::clear_output() { vertices.clear(); colors.clear(); indices.clear(); + uvs.clear(); } void LineBuilder::build() { @@ -121,6 +123,8 @@ void LineBuilder::build() { return; } + ERR_FAIL_COND(tile_aspect <= 0.f); + const float hw = width / 2.f; const float hw_sq = hw * hw; const float sharp_limit_sq = sharp_limit * sharp_limit; @@ -164,7 +168,7 @@ void LineBuilder::build() { current_distance1 = current_distance0; } else if (begin_cap_mode == Line2D::LINE_CAP_ROUND) { if (texture_mode == Line2D::LINE_TEXTURE_TILE) { - uvx0 = 0.5f; + uvx0 = 0.5f / tile_aspect; } new_arc(pos0, pos_up0 - pos0, -Math_PI, color0, Rect2(0.f, 0.f, 1.f, 1.f)); total_distance += width; @@ -286,8 +290,8 @@ void LineBuilder::build() { color1 = gradient->get_color_at_offset(current_distance1 / total_distance); } if (texture_mode == Line2D::LINE_TEXTURE_TILE) { - uvx0 = current_distance0 / width; - uvx1 = current_distance1 / width; + uvx0 = current_distance0 / (width * tile_aspect); + uvx1 = current_distance1 / (width * tile_aspect); } strip_add_quad(pos_up1, pos_down1, color1, uvx1); @@ -373,7 +377,7 @@ void LineBuilder::build() { color1 = gradient->get_color(gradient->get_points_count() - 1); } if (texture_mode == Line2D::LINE_TEXTURE_TILE) { - uvx1 = current_distance1 / width; + uvx1 = current_distance1 / (width * tile_aspect); } strip_add_quad(pos_up1, pos_down1, color1, uvx1); diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h index daa2ed7c24..b1c62f84e2 100644 --- a/scene/2d/line_builder.h +++ b/scene/2d/line_builder.h @@ -50,6 +50,7 @@ public: Line2D::LineTextureMode texture_mode; float sharp_limit; int round_precision; + float tile_aspect; // w/h // TODO offset_joints option (offers alternative implementation of round joints) // TODO Move in a struct and reference it diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 184942663f..adbb227d0c 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -4,7 +4,7 @@ void MeshInstance2D::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { if (mesh.is_valid()) { - draw_mesh(mesh, texture, normal_map, RID()); + draw_mesh(mesh, texture, normal_map); } } } diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index e63dc4e515..2cb1e86f51 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -192,7 +192,80 @@ void Polygon2D::_notification(int p_what) { // Vector<int> indices = Geometry::triangulate_polygon(points); // VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID()); - VS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID(), RID(), antialiased); + if (invert || splits.size() == 0) { + VS::get_singleton()->canvas_item_add_polygon(get_canvas_item(), points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID(), RID(), antialiased); + } else { + //use splits + Vector<int> loop; + int sc = splits.size(); + PoolVector<int>::Read r = splits.read(); + int last = points.size(); + + Vector<Vector<int> > loops; + + for (int i = 0; i < last; i++) { + + int split; + int min_end = -1; + + do { + + loop.push_back(i); + + split = -1; + int end = -1; + + for (int j = 0; j < sc; j += 2) { + if (r[j + 1] >= last) + continue; //no longer valid + if (min_end != -1 && r[j + 1] >= min_end) + continue; + if (r[j] == i) { + if (split == -1 || r[j + 1] > end) { + split = r[j]; + end = r[j + 1]; + } + } + } + + if (split != -1) { + for (int j = end; j < last; j++) { + loop.push_back(j); + } + loops.push_back(loop); + last = end + 1; + loop.clear(); + min_end = end; //avoid this split from repeating + } + + } while (split != -1); + } + + if (loop.size()) { + loops.push_back(loop); + } + + Vector<int> indices; + + for (int i = 0; i < loops.size(); i++) { + Vector<int> loop = loops[i]; + Vector<Vector2> vertices; + vertices.resize(loop.size()); + for (int j = 0; j < vertices.size(); j++) { + vertices[j] = points[loop[j]]; + } + Vector<int> sub_indices = Geometry::triangulate_polygon(vertices); + int from = indices.size(); + indices.resize(from + sub_indices.size()); + for (int j = 0; j < sub_indices.size(); j++) { + indices[from + j] = loop[sub_indices[j]]; + } + } + + //print_line("loops: " + itos(loops.size()) + " indices: " + itos(indices.size())); + + VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID()); + } } break; } @@ -220,6 +293,18 @@ PoolVector<Vector2> Polygon2D::get_uv() const { return uv; } +void Polygon2D::set_splits(const PoolVector<int> &p_splits) { + + ERR_FAIL_COND(p_splits.size() & 1); //splits should be multiple of 2 + splits = p_splits; + update(); +} + +PoolVector<int> Polygon2D::get_splits() const { + + return splits; +} + void Polygon2D::set_color(const Color &p_color) { color = p_color; @@ -352,6 +437,9 @@ void Polygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color", "color"), &Polygon2D::set_color); ClassDB::bind_method(D_METHOD("get_color"), &Polygon2D::get_color); + ClassDB::bind_method(D_METHOD("set_splits", "splits"), &Polygon2D::set_splits); + ClassDB::bind_method(D_METHOD("get_splits"), &Polygon2D::get_splits); + ClassDB::bind_method(D_METHOD("set_vertex_colors", "vertex_colors"), &Polygon2D::set_vertex_colors); ClassDB::bind_method(D_METHOD("get_vertex_colors"), &Polygon2D::get_vertex_colors); @@ -384,6 +472,7 @@ void Polygon2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv"); + ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "splits"), "set_splits", "get_splits"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index 66f44cb3f1..3a24177548 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -40,6 +40,8 @@ class Polygon2D : public Node2D { PoolVector<Vector2> polygon; PoolVector<Vector2> uv; PoolVector<Color> vertex_colors; + PoolVector<int> splits; + Color color; Ref<Texture> texture; Size2 tex_scale; @@ -75,6 +77,9 @@ public: void set_uv(const PoolVector<Vector2> &p_uv); PoolVector<Vector2> get_uv() const; + void set_splits(const PoolVector<int> &p_uv); + PoolVector<int> get_splits() const; + void set_color(const Color &p_color); Color get_color() const; diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp new file mode 100644 index 0000000000..705e82bcbb --- /dev/null +++ b/scene/2d/skeleton_2d.cpp @@ -0,0 +1,210 @@ +#include "skeleton_2d.h" + +void Bone2D::_notification(int p_what) { + + if (p_what == NOTIFICATION_ENTER_TREE) { + Node *parent = get_parent(); + parent_bone = Object::cast_to<Bone2D>(parent); + skeleton = NULL; + while (parent) { + skeleton = Object::cast_to<Skeleton2D>(parent); + if (skeleton) + break; + if (!Object::cast_to<Bone2D>(parent)) + break; //skeletons must be chained to Bone2Ds. + } + + if (skeleton) { + Skeleton2D::Bone bone; + bone.bone = this; + skeleton->bones.push_back(bone); + skeleton->_make_bone_setup_dirty(); + } + } + if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) { + if (skeleton) { + skeleton->_make_transform_dirty(); + } + } + + if (p_what == NOTIFICATION_EXIT_TREE) { + if (skeleton) { + for (int i = 0; i < skeleton->bones.size(); i++) { + if (skeleton->bones[i].bone == this) { + skeleton->bones.remove(i); + break; + } + } + skeleton->_make_bone_setup_dirty(); + skeleton = NULL; + } + parent_bone = NULL; + } +} +void Bone2D::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_rest", "rest"), &Bone2D::set_rest); + ClassDB::bind_method(D_METHOD("get_rest"), &Bone2D::get_rest); + ClassDB::bind_method(D_METHOD("apply_rest"), &Bone2D::apply_rest); +} + +void Bone2D::set_rest(const Transform2D &p_rest) { + rest = p_rest; + if (skeleton) + skeleton->_make_bone_setup_dirty(); +} + +Transform2D Bone2D::get_rest() const { + return rest; +} + +Transform2D Bone2D::get_skeleton_rest() const { + + if (parent_bone) { + return parent_bone->get_skeleton_rest() * rest; + } else { + return rest; + } +} + +void Bone2D::apply_rest() { + set_transform(rest); +} + +String Bone2D::get_configuration_warning() const { + if (!skeleton) { + if (parent_bone) { + return TTR("This Bone2D chain should end at a Skeleton2D node."); + } else { + return TTR("A Bone2D only works with a Skeleton2D or another Bone2D as parent node."); + } + } + + return Node2D::get_configuration_warning(); +} + +Bone2D::Bone2D() { + skeleton = NULL; + parent_bone = NULL; + set_notify_local_transform(true); +} + +////////////////////////////////////// + +void Skeleton2D::_make_bone_setup_dirty() { + + if (bone_setup_dirty) + return; + bone_setup_dirty = true; + if (is_inside_tree()) { + call_deferred("_update_bone_setup"); + } +} + +void Skeleton2D::_update_bone_setup() { + + if (!bone_setup_dirty) + return; + + bone_setup_dirty = false; + VS::get_singleton()->skeleton_allocate(skeleton, bones.size(), true); + + bones.sort(); //sorty so they are always in the same order/index + + for (int i = 0; i < bones.size(); i++) { + bones[i].rest_inverse = bones[i].bone->get_skeleton_rest(); //bind pose + } + + transform_dirty = true; + _update_transform(); +} + +void Skeleton2D::_make_transform_dirty() { + + if (transform_dirty) + return; + transform_dirty = true; + if (is_inside_tree()) { + call_deferred("_update_transform"); + } +} + +void Skeleton2D::_update_transform() { + + if (bone_setup_dirty) { + _update_bone_setup(); + return; //above will update transform anyway + } + if (!transform_dirty) + return; + + transform_dirty = false; + + Transform2D global_xform = get_global_transform(); + Transform2D global_xform_inverse = global_xform.affine_inverse(); + + for (int i = 0; i < bones.size(); i++) { + + Transform2D final_xform = bones[i].rest_inverse * bones[i].bone->get_relative_transform_to_parent(this); + VS::get_singleton()->skeleton_bone_set_transform_2d(skeleton, i, global_xform * (final_xform * global_xform_inverse)); + } +} + +int Skeleton2D::get_bone_count() const { + + ERR_FAIL_COND_V(!is_inside_tree(), 0); + + if (bone_setup_dirty) { + const_cast<Skeleton2D *>(this)->_update_bone_setup(); + } + + return bones.size(); +} + +Bone2D *Skeleton2D::get_bone(int p_idx) { + + ERR_FAIL_COND_V(!is_inside_tree(), NULL); + ERR_FAIL_INDEX_V(p_idx, bones.size(), NULL); + + return bones[p_idx].bone; +} + +void Skeleton2D::_notification(int p_what) { + + if (p_what == NOTIFICATION_READY) { + + if (bone_setup_dirty) + _update_bone_setup(); + if (transform_dirty) + _update_transform(); + } + + if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { + _make_transform_dirty(); + } +} + +RID Skeleton2D::get_skeleton() const { + return skeleton; +} +void Skeleton2D::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_update_bone_setup"), &Skeleton2D::_update_bone_setup); + ClassDB::bind_method(D_METHOD("_update_transform"), &Skeleton2D::_update_transform); + + ClassDB::bind_method(D_METHOD("get_bone_count"), &Skeleton2D::get_bone_count); + ClassDB::bind_method(D_METHOD("get_bone"), &Skeleton2D::get_bone); + + ClassDB::bind_method(D_METHOD("get_skeleton"), &Skeleton2D::get_skeleton); +} + +Skeleton2D::Skeleton2D() { + bone_setup_dirty = true; + transform_dirty = true; + skeleton = VS::get_singleton()->skeleton_create(); +} + +Skeleton2D::~Skeleton2D() { + + VS::get_singleton()->free(skeleton); +} diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h new file mode 100644 index 0000000000..49199f684f --- /dev/null +++ b/scene/2d/skeleton_2d.h @@ -0,0 +1,68 @@ +#ifndef SKELETON_2D_H +#define SKELETON_2D_H + +#include "scene/2d/node_2d.h" + +class Skeleton2D; + +class Bone2D : public Node2D { + GDCLASS(Bone2D, Node2D) + + Bone2D *parent_bone; + Skeleton2D *skeleton; + Transform2D rest; + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + void set_rest(const Transform2D &p_rest); + Transform2D get_rest() const; + void apply_rest(); + Transform2D get_skeleton_rest() const; + + String get_configuration_warning() const; + + Bone2D(); +}; + +class Skeleton2D : public Node2D { + GDCLASS(Skeleton2D, Node2D); + + friend class Bone2D; + + struct Bone { + bool operator<(const Bone &p_bone) const { + return p_bone.bone->is_greater_than(bone); + } + Bone2D *bone; + Transform2D rest_inverse; + }; + + Vector<Bone> bones; + + bool bone_setup_dirty; + void _make_bone_setup_dirty(); + void _update_bone_setup(); + + bool transform_dirty; + void _make_transform_dirty(); + void _update_transform(); + + RID skeleton; + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + int get_bone_count() const; + Bone2D *get_bone(int p_idx); + + RID get_skeleton() const; + Skeleton2D(); + ~Skeleton2D(); +}; + +#endif // SKELETON_2D_H diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 796969be1e..67f016ae79 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -73,8 +73,8 @@ void Sprite::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_cli s = s / Size2(hframes, vframes); r_src_rect.size = s; - r_src_rect.position.x += float(frame % hframes) * s.x; - r_src_rect.position.y += float(frame / hframes) * s.y; + r_src_rect.position.x = float(frame % hframes) * s.x; + r_src_rect.position.y = float(frame / hframes) * s.y; } Point2 ofs = offset; @@ -121,7 +121,15 @@ void Sprite::set_texture(const Ref<Texture> &p_texture) { if (p_texture == texture) return; + + if (texture.is_valid()) + texture->remove_change_receptor(this); + texture = p_texture; + + if (texture.is_valid()) + texture->add_change_receptor(this); + update(); emit_signal("texture_changed"); item_rect_changed(); @@ -281,13 +289,39 @@ bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc Rect2 src_rect, dst_rect; bool filter_clip; _get_rects(src_rect, dst_rect, filter_clip); + dst_rect.size = dst_rect.size.abs(); if (!dst_rect.has_point(p_point)) return false; - Vector2 q = ((p_point - dst_rect.position) / dst_rect.size) * src_rect.size + src_rect.position; + Vector2 q = (p_point - dst_rect.position) / dst_rect.size; + if (hflip) + q.x = 1.0f - q.x; + if (vflip) + q.y = 1.0f - q.y; + q = q * src_rect.size + src_rect.position; + + Ref<Image> image; + Ref<AtlasTexture> atlasTexture = texture; + if (atlasTexture.is_null()) { + image = texture->get_data(); + } else { + ERR_FAIL_COND_V(atlasTexture->get_atlas().is_null(), false); + + image = atlasTexture->get_atlas()->get_data(); + + Rect2 region = atlasTexture->get_region(); + Rect2 margin = atlasTexture->get_margin(); + + q -= margin.position; + + if ((q.x > region.size.width) || (q.y > region.size.height)) { + return false; + } + + q += region.position; + } - Ref<Image> image = texture->get_data(); ERR_FAIL_COND_V(image.is_null(), false); image->lock(); @@ -336,6 +370,15 @@ void Sprite::_validate_property(PropertyInfo &property) const { } } +void Sprite::_changed_callback(Object *p_changed, const char *p_prop) { + + // Changes to the texture need to trigger an update to make + // the editor redraw the sprite with the updated texture. + if (texture.is_valid() && texture.ptr() == p_changed) { + update(); + } +} + void Sprite::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Sprite::set_texture); @@ -410,3 +453,8 @@ Sprite::Sprite() { vframes = 1; hframes = 1; } + +Sprite::~Sprite() { + if (texture.is_valid()) + texture->remove_change_receptor(this); +} diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index dd3719099f..abd04515ec 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -64,6 +64,8 @@ protected: virtual void _validate_property(PropertyInfo &property) const; + virtual void _changed_callback(Object *p_changed, const char *p_prop); + public: virtual Dictionary _edit_get_state() const; virtual void _edit_set_state(const Dictionary &p_state); @@ -113,6 +115,7 @@ public: Rect2 get_rect() const; Sprite(); + ~Sprite(); }; #endif // SPRITE_H diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 2aa55e2825..c126dd8f6b 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -142,16 +142,20 @@ void TileMap::_update_quadrant_transform() { void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { - if (tile_set.is_valid()) + if (tile_set.is_valid()) { tile_set->disconnect("changed", this, "_recreate_quadrants"); + tile_set->remove_change_receptor(this); + } _clear_quadrants(); tile_set = p_tileset; - if (tile_set.is_valid()) + if (tile_set.is_valid()) { tile_set->connect("changed", this, "_recreate_quadrants"); - else + tile_set->add_change_receptor(this); + } else { clear(); + } _recreate_quadrants(); emit_signal("settings_changed"); @@ -261,12 +265,18 @@ void TileMap::_update_dirty_quadrants() { SceneTree *st = SceneTree::get_singleton(); Color debug_collision_color; + Color debug_navigation_color; bool debug_shapes = st && st->is_debugging_collisions_hint(); if (debug_shapes) { debug_collision_color = st->get_debug_collisions_color(); } + bool debug_navigation = st && st->is_debugging_navigation_hint(); + if (debug_navigation) { + debug_navigation_color = st->get_debug_navigation_color(); + } + while (dirty_quadrant_list.first()) { Quadrant &q = *dirty_quadrant_list.first()->self(); @@ -493,6 +503,55 @@ void TileMap::_update_dirty_quadrants() { np.id = pid; np.xform = xform; q.navpoly_ids[E->key()] = np; + + if (debug_navigation) { + RID debug_navigation_item = vs->canvas_item_create(); + vs->canvas_item_set_parent(debug_navigation_item, canvas_item); + vs->canvas_item_set_z_as_relative_to_parent(debug_navigation_item, false); + vs->canvas_item_set_z_index(debug_navigation_item, VS::CANVAS_ITEM_Z_MAX - 2); // Display one below collision debug + + if (debug_navigation_item.is_valid()) { + PoolVector<Vector2> navigation_polygon_vertices = navpoly->get_vertices(); + int vsize = navigation_polygon_vertices.size(); + + if (vsize > 2) { + Vector<Color> colors; + Vector<Vector2> vertices; + vertices.resize(vsize); + colors.resize(vsize); + { + PoolVector<Vector2>::Read vr = navigation_polygon_vertices.read(); + for (int i = 0; i < vsize; i++) { + vertices[i] = vr[i]; + colors[i] = debug_navigation_color; + } + } + + Vector<int> indices; + + for (int i = 0; i < navpoly->get_polygon_count(); i++) { + Vector<int> polygon = navpoly->get_polygon(i); + + for (int j = 2; j < polygon.size(); j++) { + + int kofs[3] = { 0, j - 1, j }; + for (int k = 0; k < 3; k++) { + + int idx = polygon[kofs[k]]; + ERR_FAIL_INDEX(idx, vsize); + indices.push_back(idx); + } + } + } + Transform2D navxform; + navxform.set_origin(offset.floor()); + _fix_cell_transform(navxform, c, npoly_ofs + center_ofs, s); + + vs->canvas_item_set_transform(debug_navigation_item, navxform); + vs->canvas_item_add_triangle_array(debug_navigation_item, indices, vertices, colors); + } + } + } } } @@ -830,6 +889,16 @@ void TileMap::update_dirty_bitmask() { } } +void TileMap::fix_invalid_tiles() { + + for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { + + if (!tile_set->has_tile(get_cell(E->key().x, E->key().y))) { + set_cell(E->key().x, E->key().y, INVALID_CELL); + } + } +} + int TileMap::get_cell(int p_x, int p_y) const { PosKey pk(p_x, p_y); @@ -1515,6 +1584,7 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("is_cell_y_flipped", "x", "y"), &TileMap::is_cell_y_flipped); ClassDB::bind_method(D_METHOD("is_cell_transposed", "x", "y"), &TileMap::is_cell_transposed); + ClassDB::bind_method(D_METHOD("fix_invalid_tiles"), &TileMap::fix_invalid_tiles); ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear); ClassDB::bind_method(D_METHOD("get_used_cells"), &TileMap::get_used_cells); @@ -1573,6 +1643,12 @@ void TileMap::_bind_methods() { BIND_ENUM_CONSTANT(TILE_ORIGIN_BOTTOM_LEFT); } +void TileMap::_changed_callback(Object *p_changed, const char *p_prop) { + if (tile_set.is_valid() && tile_set.ptr() == p_changed) { + emit_signal("settings_changed"); + } +} + TileMap::TileMap() { rect_cache_dirty = true; @@ -1601,5 +1677,8 @@ TileMap::TileMap() { TileMap::~TileMap() { + if (tile_set.is_valid()) + tile_set->remove_change_receptor(this); + clear(); } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 973e527b42..587bd3b684 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -217,6 +217,8 @@ protected: void _notification(int p_what); static void _bind_methods(); + virtual void _changed_callback(Object *p_changed, const char *p_prop); + public: enum { INVALID_CELL = -1 @@ -308,6 +310,7 @@ public: void set_clip_uv(bool p_enable); bool get_clip_uv() const; + void fix_invalid_tiles(); void clear(); TileMap(); diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index d448ef024d..c2a50ec7bb 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -536,14 +536,14 @@ void AudioStreamPlayer3D::_notification(int p_what) { setseek = setplay; active = true; setplay = -1; - //do not update, this makes it easier to animate (will shut off otherise) + //do not update, this makes it easier to animate (will shut off otherwise) ///_change_notify("playing"); //update property in editor } //stop playing if no longer active if (!active) { set_physics_process_internal(false); - //do not update, this makes it easier to animate (will shut off otherise) + //do not update, this makes it easier to animate (will shut off otherwise) //_change_notify("playing"); //update property in editor emit_signal("finished"); } diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 6998b34cfd..9de189c158 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -201,7 +201,7 @@ void Camera::make_current() { //get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,camera_group,"_camera_make_current",this); } -void Camera::clear_current() { +void Camera::clear_current(bool p_enable_next) { current = false; if (!is_inside_tree()) @@ -209,7 +209,10 @@ void Camera::clear_current() { if (get_viewport()->get_camera() == this) { get_viewport()->_camera_set(NULL); - get_viewport()->_camera_make_next_current(this); + + if (p_enable_next) { + get_viewport()->_camera_make_next_current(this); + } } } @@ -439,7 +442,7 @@ void Camera::_bind_methods() { ClassDB::bind_method(D_METHOD("set_perspective", "fov", "z_near", "z_far"), &Camera::set_perspective); ClassDB::bind_method(D_METHOD("set_orthogonal", "size", "z_near", "z_far"), &Camera::set_orthogonal); ClassDB::bind_method(D_METHOD("make_current"), &Camera::make_current); - ClassDB::bind_method(D_METHOD("clear_current"), &Camera::clear_current); + ClassDB::bind_method(D_METHOD("clear_current", "enable_next"), &Camera::clear_current, DEFVAL(true)); ClassDB::bind_method(D_METHOD("set_current"), &Camera::set_current); ClassDB::bind_method(D_METHOD("is_current"), &Camera::is_current); ClassDB::bind_method(D_METHOD("get_camera_transform"), &Camera::get_camera_transform); diff --git a/scene/3d/camera.h b/scene/3d/camera.h index e2679870de..109bf3adc6 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -113,7 +113,7 @@ public: void set_projection(Camera::Projection p_mode); void make_current(); - void clear_current(); + void clear_current(bool p_enable_next = true); void set_current(bool p_current); bool is_current() const; diff --git a/scene/3d/interpolated_camera.cpp b/scene/3d/interpolated_camera.cpp index 9865fe156a..ffa283f634 100644 --- a/scene/3d/interpolated_camera.cpp +++ b/scene/3d/interpolated_camera.cpp @@ -38,10 +38,10 @@ void InterpolatedCamera::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { if (Engine::get_singleton()->is_editor_hint() && enabled) - set_physics_process(false); + set_process_internal(false); } break; - case NOTIFICATION_PROCESS: { + case NOTIFICATION_INTERNAL_PROCESS: { if (!enabled) break; @@ -111,9 +111,9 @@ void InterpolatedCamera::set_interpolation_enabled(bool p_enable) { if (p_enable) { if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) return; - set_process(true); + set_process_internal(true); } else - set_process(false); + set_process_internal(false); } bool InterpolatedCamera::is_interpolation_enabled() const { diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp index e7ab6cde8a..77bf703706 100644 --- a/scene/3d/navigation.cpp +++ b/scene/3d/navigation.cpp @@ -35,6 +35,7 @@ void Navigation::_navmesh_link(int p_id) { ERR_FAIL_COND(!navmesh_map.has(p_id)); NavMesh &nm = navmesh_map[p_id]; ERR_FAIL_COND(nm.linked); + ERR_FAIL_COND(nm.navmesh.is_null()); PoolVector<Vector3> vertices = nm.navmesh->get_vertices(); int len = vertices.size(); diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index 8617bbc2f6..693b416f6d 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -849,9 +849,9 @@ void ParticlesMaterial::_update_shader() { code += " vec4(1.250, -1.050, -0.203, 0.0),\n"; code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n"; if (color_ramp.is_valid()) { - code += " COLOR = textureLod(color_ramp,vec2(CUSTOM.y,0.0),0.0) * hue_rot_mat;\n"; + code += " COLOR = hue_rot_mat * textureLod(color_ramp,vec2(CUSTOM.y,0.0),0.0);\n"; } else { - code += " COLOR = color_value * hue_rot_mat;\n"; + code += " COLOR = hue_rot_mat * color_value;\n"; } if (emission_color_texture.is_valid() && emission_shape >= EMISSION_SHAPE_POINTS) { code += " COLOR*= texelFetch(emission_texture_color,emission_tex_ofs,0);\n"; diff --git a/scene/3d/scenario_fx.cpp b/scene/3d/scenario_fx.cpp index 02768ac91f..d5bff676cb 100644 --- a/scene/3d/scenario_fx.cpp +++ b/scene/3d/scenario_fx.cpp @@ -79,7 +79,11 @@ Ref<Environment> WorldEnvironment::get_environment() const { String WorldEnvironment::get_configuration_warning() const { - if (/*!is_visible_in_tree() ||*/ !is_inside_tree() || !environment.is_valid()) + if (!environment.is_valid()) { + return TTR("WorldEnvironment needs an Environment resource."); + } + + if (/*!is_visible_in_tree() ||*/ !is_inside_tree()) return String(); List<Node *> nodes; @@ -89,6 +93,10 @@ String WorldEnvironment::get_configuration_warning() const { return TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."); } + if (environment.is_valid() && get_viewport() && !get_viewport()->get_camera() && environment->get_background() != Environment::BG_CANVAS) { + return TTR("This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set this environment's Background Mode to Canvas (for 2D scenes)."); + } + return String(); } diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index 721641e09b..f8a5c7f400 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -188,7 +188,9 @@ void Spatial::_notification(int p_what) { if (data.gizmo.is_valid()) { data.gizmo->create(); if (data.gizmo->can_draw()) { - data.gizmo->redraw(); + if (is_visible_in_tree()) { + data.gizmo->redraw(); + } } data.gizmo->transform(); } @@ -409,7 +411,9 @@ void Spatial::set_gizmo(const Ref<SpatialGizmo> &p_gizmo) { data.gizmo->create(); if (data.gizmo->can_draw()) { - data.gizmo->redraw(); + if (is_visible_in_tree()) { + data.gizmo->redraw(); + } } data.gizmo->transform(); } diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp index ed3bde9504..b72665aa2b 100644 --- a/scene/3d/vehicle_body.cpp +++ b/scene/3d/vehicle_body.cpp @@ -524,7 +524,7 @@ void VehicleBody::_update_suspension(PhysicsDirectBodyState *s) { //bilateral constraint between two dynamic objects void VehicleBody::_resolve_single_bilateral(PhysicsDirectBodyState *s, const Vector3 &pos1, - PhysicsBody *body2, const Vector3 &pos2, const Vector3 &normal, real_t &impulse) { + PhysicsBody *body2, const Vector3 &pos2, const Vector3 &normal, real_t &impulse, real_t p_rollInfluence) { real_t normalLenSqr = normal.length_squared(); //ERR_FAIL_COND( normalLenSqr < real_t(1.1)); @@ -582,8 +582,12 @@ void VehicleBody::_resolve_single_bilateral(PhysicsDirectBodyState *s, const Vec rel_vel = normal.dot(vel); - //TODO: move this into proper structure - real_t contactDamping = real_t(0.4); + // !BAS! We had this set to 0.4, in bullet its 0.2 + // real_t contactDamping = real_t(0.2); + + // !BAS! But seeing we apply this frame by frame, makes more sense to me to make this time based + // keeping in mind our anti roll factor + real_t contactDamping = s->get_step() / p_rollInfluence; #define ONLY_USE_LINEAR_MASS #ifdef ONLY_USE_LINEAR_MASS real_t massTerm = real_t(1.) / ((1.0 / mass) + b2invmass); @@ -704,7 +708,7 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) { _resolve_single_bilateral(s, wheelInfo.m_raycastInfo.m_contactPointWS, wheelInfo.m_raycastInfo.m_groundObject, wheelInfo.m_raycastInfo.m_contactPointWS, - m_axle[i], m_sideImpulse[i]); + m_axle[i], m_sideImpulse[i], wheelInfo.m_rollInfluence); m_sideImpulse[i] *= sideFrictionStiffness2; } diff --git a/scene/3d/vehicle_body.h b/scene/3d/vehicle_body.h index 7810a42e8a..1ac3693cc4 100644 --- a/scene/3d/vehicle_body.h +++ b/scene/3d/vehicle_body.h @@ -168,7 +168,7 @@ class VehicleBody : public RigidBody { btVehicleWheelContactPoint(PhysicsDirectBodyState *s, PhysicsBody *body1, const Vector3 &frictionPosWorld, const Vector3 &frictionDirectionWorld, real_t maxImpulse); }; - void _resolve_single_bilateral(PhysicsDirectBodyState *s, const Vector3 &pos1, PhysicsBody *body2, const Vector3 &pos2, const Vector3 &normal, real_t &impulse); + void _resolve_single_bilateral(PhysicsDirectBodyState *s, const Vector3 &pos1, PhysicsBody *body2, const Vector3 &pos2, const Vector3 &normal, real_t &impulse, real_t p_rollInfluence); real_t _calc_rolling_friction(btVehicleWheelContactPoint &contactPoint); void _update_friction(PhysicsDirectBodyState *s); diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 9db4a5fb04..2cf488ade4 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -590,8 +590,8 @@ void AnimationPlayer::_animation_update_transforms() { Transform t; t.origin = nc->loc_accum; - t.basis = nc->rot_accum; t.basis.scale(nc->scale_accum); + t.basis.rotate(nc->rot_accum.get_euler()); if (nc->skeleton && nc->bone_idx >= 0) { @@ -1010,6 +1010,7 @@ void AnimationPlayer::stop(bool p_reset) { c.blend.clear(); if (p_reset) { c.current.from = NULL; + c.current.speed_scale = 1; } _set_process(false); queued.clear(); diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index 89f0e43a86..e811b7a7b3 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -895,13 +895,13 @@ void AnimationTreePlayer::_process_animation(float p_delta) { } Transform xform; - xform.basis = t.rot; xform.origin = t.loc; t.scale.x += 1.0; t.scale.y += 1.0; t.scale.z += 1.0; xform.basis.scale(t.scale); + xform.basis.rotate(t.rot.get_euler()); if (t.bone_idx >= 0) { if (t.skeleton) diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 5f541ea16a..562dd155f9 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -211,6 +211,11 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) { if (!toggle_mode) { //mouse press attempt pressed(); + if (get_script_instance()) { + Variant::CallError ce; + get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce); + } + emit_signal("pressed"); } else { diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 30bcc48149..31be18612f 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -77,8 +77,7 @@ void ColorPicker::_notification(int p_what) { void ColorPicker::set_focus_on_line_edit() { - c_text->grab_focus(); - c_text->select(); + c_text->call_deferred("grab_focus"); } void ColorPicker::_update_controls() { @@ -159,14 +158,16 @@ void ColorPicker::_update_color() { updating = true; for (int i = 0; i < 4; i++) { - scroll[i]->set_max(255); scroll[i]->set_step(0.01); if (raw_mode_enabled) { + scroll[i]->set_max(100); if (i == 3) scroll[i]->set_max(1); scroll[i]->set_value(color.components[i]); } else { - scroll[i]->set_value(color.components[i] * 255); + const int byte_value = color.components[i] * 255; + scroll[i]->set_max(next_power_of_2(MAX(255, byte_value)) - 1); + scroll[i]->set_value(byte_value); } } @@ -242,6 +243,7 @@ bool ColorPicker::is_raw_mode() const { } void ColorPicker::_update_text_value() { + bool visible = true; if (text_is_constructor) { String t = "Color(" + String::num(color.r) + "," + String::num(color.g) + "," + String::num(color.b); if (edit_alpha && color.a < 1) @@ -250,8 +252,13 @@ void ColorPicker::_update_text_value() { t += ")"; c_text->set_text(t); } else { - c_text->set_text(color.to_html(edit_alpha && color.a < 1)); + if (color.r > 1 || color.g > 1 || color.b > 1 || color.r < 0 || color.g < 0 || color.b < 0) { + visible = false; + } else { + c_text->set_text(color.to_html(edit_alpha && color.a < 1)); + } } + c_text->set_visible(visible); } void ColorPicker::_sample_draw() { @@ -462,6 +469,31 @@ void ColorPicker::_screen_pick_pressed() { screen->show_modal(); } +void ColorPicker::_focus_enter() { + if (c_text->has_focus()) { + c_text->select_all(); + return; + } + for (int i = 0; i < 4; i++) { + if (values[i]->get_line_edit()->has_focus()) { + values[i]->get_line_edit()->select_all(); + break; + } + } +} + +void ColorPicker::_focus_exit() { + for (int i = 0; i < 4; i++) { + values[i]->get_line_edit()->select(0, 0); + } + c_text->select(0, 0); +} + +void ColorPicker::_html_focus_exit() { + _html_entered(c_text->get_text()); + _focus_exit(); +} + void ColorPicker::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pick_color", "color"), &ColorPicker::set_pick_color); @@ -483,6 +515,9 @@ void ColorPicker::_bind_methods() { ClassDB::bind_method(D_METHOD("_w_input"), &ColorPicker::_w_input); ClassDB::bind_method(D_METHOD("_preset_input"), &ColorPicker::_preset_input); ClassDB::bind_method(D_METHOD("_screen_input"), &ColorPicker::_screen_input); + ClassDB::bind_method(D_METHOD("_focus_enter"), &ColorPicker::_focus_enter); + ClassDB::bind_method(D_METHOD("_focus_exit"), &ColorPicker::_focus_exit); + ClassDB::bind_method(D_METHOD("_html_focus_exit"), &ColorPicker::_html_focus_exit); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_pick_color", "get_pick_color"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "edit_alpha"), "set_edit_alpha", "is_editing_alpha"); @@ -559,11 +594,14 @@ ColorPicker::ColorPicker() : scroll[i] = memnew(HSlider); scroll[i]->set_v_size_flags(SIZE_SHRINK_CENTER); + scroll[i]->set_focus_mode(FOCUS_NONE); hbc->add_child(scroll[i]); values[i] = memnew(SpinBox); scroll[i]->share(values[i]); hbc->add_child(values[i]); + values[i]->get_line_edit()->connect("focus_entered", this, "_focus_enter"); + values[i]->get_line_edit()->connect("focus_exited", this, "_focus_exit"); scroll[i]->set_min(0); scroll[i]->set_page(0); @@ -589,6 +627,9 @@ ColorPicker::ColorPicker() : c_text = memnew(LineEdit); hhb->add_child(c_text); c_text->connect("text_entered", this, "_html_entered"); + c_text->connect("focus_entered", this, "_focus_enter"); + c_text->connect("focus_exited", this, "_html_focus_exit"); + text_type->set_text("#"); c_text->set_h_size_flags(SIZE_EXPAND_FILL); diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 01ae1cc464..40ded4fff5 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -88,6 +88,9 @@ private: void _screen_input(const Ref<InputEvent> &p_event); void _add_preset_pressed(); void _screen_pick_pressed(); + void _focus_enter(); + void _focus_exit(); + void _html_focus_exit(); protected: void _notification(int); diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index e61ede7c3d..feb080dd06 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -108,7 +108,7 @@ class AcceptDialog : public WindowDialog { HBoxContainer *hbc; Label *label; Button *ok; - //Button *cancel; no more cancel (there is X on tht titlebar) + //Button *cancel; no more cancel (there is X on that titlebar) bool hide_on_ok; void _custom_action(const String &p_action); diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index 3985039716..9fc8e98a7f 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -367,6 +367,13 @@ void GradientEdit::_notification(int p_what) { draw_line(Vector2(-1, -1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6)); } } + + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { + + if (!is_visible()) { + grabbing = false; + } + } } void GradientEdit::_draw_checker(int x, int y, int w, int h) { diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index c2b8a7dfab..b401abd436 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -36,10 +36,10 @@ void GridContainer::_notification(int p_what) { case NOTIFICATION_SORT_CHILDREN: { - Map<int, int> col_minw; - Map<int, int> row_minh; - Set<int> col_expanded; - Set<int> row_expanded; + Map<int, int> col_minw; // max of min_width of all controls in each col (indexed by col) + Map<int, int> row_minh; // max of min_height of all controls in each row (indexed by row) + Set<int> col_expanded; // columns which have the SIZE_EXPAND flag set + Set<int> row_expanded; // rows which have the SIZE_EXPAND flag set int hsep = get_constant("hseparation"); int vsep = get_constant("vseparation"); @@ -84,17 +84,17 @@ void GridContainer::_notification(int p_what) { if (!row_expanded.has(E->key())) remaining_space.height -= E->get(); } - remaining_space.height -= vsep * (max_row - 1); - remaining_space.width -= hsep * (max_col - 1); + remaining_space.height -= vsep * MAX(max_row - 1, 0); + remaining_space.width -= hsep * MAX(max_col - 1, 0); bool can_fit = false; - while (!can_fit) { + while (!can_fit && col_expanded.size() > 0) { // Check if all minwidth constraints are ok if we use the remaining space can_fit = true; - int max_index = 0; + int max_index = col_expanded.front()->get(); for (Set<int>::Element *E = col_expanded.front(); E; E = E->next()) { if (col_minw[E->get()] > col_minw[max_index]) { - max_index = col_minw[E->get()]; + max_index = E->get(); } if (can_fit && (remaining_space.width / col_expanded.size()) < col_minw[E->get()]) { can_fit = false; @@ -109,13 +109,13 @@ void GridContainer::_notification(int p_what) { } can_fit = false; - while (!can_fit) { + while (!can_fit && row_expanded.size() > 0) { // Check if all minwidth constraints are ok if we use the remaining space can_fit = true; - int max_index = 0; + int max_index = row_expanded.front()->get(); for (Set<int>::Element *E = row_expanded.front(); E; E = E->next()) { if (row_minh[E->get()] > row_minh[max_index]) { - max_index = row_minh[E->get()]; + max_index = E->get(); } if (can_fit && (remaining_space.height / row_expanded.size()) < row_minh[E->get()]) { can_fit = false; @@ -130,8 +130,8 @@ void GridContainer::_notification(int p_what) { } // Finally, fit the nodes - int col_expand = remaining_space.width / col_expanded.size(); - int row_expand = remaining_space.height / row_expanded.size(); + int col_expand = col_expanded.size() > 0 ? remaining_space.width / col_expanded.size() : 0; + int row_expand = row_expanded.size() > 0 ? remaining_space.height / row_expanded.size() : 0; int col_ofs = 0; int row_ofs = 0; diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index f7574ca2cd..cc17e6bcd8 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -295,35 +295,21 @@ int ItemList::get_current() const { return current; } -void ItemList::move_item(int p_item, int p_to_pos) { +void ItemList::move_item(int p_from_idx, int p_to_idx) { - ERR_FAIL_INDEX(p_item, items.size()); - ERR_FAIL_INDEX(p_to_pos, items.size() + 1); + ERR_FAIL_INDEX(p_from_idx, items.size()); + ERR_FAIL_INDEX(p_to_idx, items.size()); - Item it = items[p_item]; - items.remove(p_item); - - if (p_to_pos > p_item) { - p_to_pos--; + if (is_anything_selected() && get_selected_items()[0] == p_from_idx) { + current = p_to_idx; } - if (p_to_pos >= items.size()) { - items.push_back(it); - } else { - items.insert(p_to_pos, it); - } - - if (current < 0) { - //do none - } else if (p_item == current) { - current = p_to_pos; - } else if (p_to_pos > p_item && current > p_item && current < p_to_pos) { - current--; - } else if (p_to_pos < p_item && current < p_item && current > p_to_pos) { - current++; - } + Item item = items[p_from_idx]; + items.remove(p_from_idx); + items.insert(p_to_idx, item); update(); + shape_changed = true; } int ItemList::get_item_count() const { @@ -1423,9 +1409,13 @@ void ItemList::_bind_methods() { ClassDB::bind_method(D_METHOD("select", "idx", "single"), &ItemList::select, DEFVAL(true)); ClassDB::bind_method(D_METHOD("unselect", "idx"), &ItemList::unselect); + ClassDB::bind_method(D_METHOD("unselect_all"), &ItemList::unselect_all); + ClassDB::bind_method(D_METHOD("is_selected", "idx"), &ItemList::is_selected); ClassDB::bind_method(D_METHOD("get_selected_items"), &ItemList::get_selected_items); + ClassDB::bind_method(D_METHOD("move_item", "p_from_idx", "p_to_idx"), &ItemList::move_item); + ClassDB::bind_method(D_METHOD("get_item_count"), &ItemList::get_item_count); ClassDB::bind_method(D_METHOD("remove_item", "idx"), &ItemList::remove_item); @@ -1465,6 +1455,8 @@ void ItemList::_bind_methods() { ClassDB::bind_method(D_METHOD("set_auto_height", "enable"), &ItemList::set_auto_height); ClassDB::bind_method(D_METHOD("has_auto_height"), &ItemList::has_auto_height); + ClassDB::bind_method(D_METHOD("is_anything_selected"), &ItemList::is_anything_selected); + ClassDB::bind_method(D_METHOD("get_item_at_position", "position", "exact"), &ItemList::get_item_at_position, DEFVAL(false)); ClassDB::bind_method(D_METHOD("ensure_current_is_visible"), &ItemList::ensure_current_is_visible); diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index 7f34a250bd..0fa0dd415b 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -169,7 +169,7 @@ public: void set_current(int p_current); int get_current() const; - void move_item(int p_item, int p_to_pos); + void move_item(int p_from_idx, int p_to_idx); int get_item_count() const; void remove_item(int p_idx); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 03dc6686b8..5c0e8fefc7 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -373,12 +373,14 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { case KEY_UP: { shift_selection_check_pre(k->get_shift()); + if (get_cursor_position() == 0) handled = false; set_cursor_position(0); shift_selection_check_post(k->get_shift()); } break; case KEY_DOWN: { shift_selection_check_pre(k->get_shift()); + if (get_cursor_position() == text.length()) handled = false; set_cursor_position(text.length()); shift_selection_check_post(k->get_shift()); } break; diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 2e74faa61d..87cf4dc334 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -59,7 +59,6 @@ void MenuButton::pressed() { popup->set_size(Size2(size.width, 0)); popup->set_parent_rect(Rect2(Point2(gp - popup->get_global_position()), get_size())); popup->popup(); - popup->set_invalidate_click_until_motion(); } void MenuButton::_gui_input(Ref<InputEvent> p_event) { @@ -109,7 +108,6 @@ MenuButton::MenuButton() { add_child(popup); popup->set_as_toplevel(true); popup->set_pass_on_modal_close_click(false); - connect("button_up", popup, "call_deferred", make_binds("grab_click_focus")); set_process_unhandled_key_input(true); set_action_mode(ACTION_MODE_BUTTON_PRESS); } diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 71c14810f6..aaad10f579 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -75,6 +75,10 @@ void OptionButton::_notification(int p_what) { } } +void OptionButton::_focused(int p_which) { + emit_signal("item_focused", p_which); +} + void OptionButton::_selected(int p_which) { int selid = -1; @@ -114,7 +118,7 @@ void OptionButton::add_icon_item(const Ref<Texture> &p_icon, const String &p_lab } void OptionButton::add_item(const String &p_label, int p_ID) { - popup->add_check_item(p_label, p_ID); + popup->add_radio_check_item(p_label, p_ID); if (popup->get_item_count() == 1) select(0); } @@ -290,6 +294,7 @@ void OptionButton::get_translatable_strings(List<String> *p_strings) const { void OptionButton::_bind_methods() { ClassDB::bind_method(D_METHOD("_selected"), &OptionButton::_selected); + ClassDB::bind_method(D_METHOD("_focused"), &OptionButton::_focused); ClassDB::bind_method(D_METHOD("add_item", "label", "id"), &OptionButton::add_item, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("add_icon_item", "texture", "label", "id"), &OptionButton::add_icon_item); @@ -322,6 +327,7 @@ void OptionButton::_bind_methods() { // "selected" property must come after "items", otherwise GH-10213 occurs ADD_PROPERTY(PropertyInfo(Variant::INT, "selected"), "_select_int", "get_selected"); ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "ID"))); + ADD_SIGNAL(MethodInfo("item_focused", PropertyInfo(Variant::INT, "ID"))); } OptionButton::OptionButton() { @@ -336,6 +342,7 @@ OptionButton::OptionButton() { popup->set_as_toplevel(true); popup->set_pass_on_modal_close_click(false); popup->connect("id_pressed", this, "_selected"); + popup->connect("id_focused", this, "_focused"); } OptionButton::~OptionButton() { diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index f65fa1b631..d5f866d806 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -43,6 +43,7 @@ class OptionButton : public Button { PopupMenu *popup; int current; + void _focused(int p_which); void _selected(int p_which); void _select(int p_which, bool p_emit = false); void _select_int(int p_which); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 89000fcde1..9ff3bd6e81 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -55,7 +55,7 @@ Size2 PopupMenu::get_minimum_size() const { float max_w = 0; int font_h = font->get_height(); - int check_w = get_icon("checked")->get_width(); + int check_w = MAX(get_icon("checked")->get_width(), get_icon("radio_checked")->get_width()); int accel_max_w = 0; for (int i = 0; i < items.size(); i++) { @@ -74,7 +74,7 @@ Size2 PopupMenu::get_minimum_size() const { size.width += items[i].h_ofs; - if (items[i].checkable) { + if (items[i].checkable_type) { size.width += check_w + hseparation; } @@ -211,86 +211,69 @@ void PopupMenu::_scroll(float p_factor, const Point2 &p_over) { void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) { - Ref<InputEventKey> k = p_event; - - if (k.is_valid()) { - - if (!k->is_pressed()) - return; + if (p_event->is_action("ui_down") && p_event->is_pressed()) { - switch (k->get_scancode()) { + int search_from = mouse_over + 1; + if (search_from >= items.size()) + search_from = 0; - case KEY_DOWN: { + for (int i = search_from; i < items.size(); i++) { - int search_from = mouse_over + 1; - if (search_from >= items.size()) - search_from = 0; - - for (int i = search_from; i < items.size(); i++) { - - if (i < 0 || i >= items.size()) - continue; - - if (!items[i].separator && !items[i].disabled) { - - mouse_over = i; - update(); - break; - } - } - } break; - case KEY_UP: { - - int search_from = mouse_over - 1; - if (search_from < 0) - search_from = items.size() - 1; - - for (int i = search_from; i >= 0; i--) { - - if (i < 0 || i >= items.size()) - continue; - - if (!items[i].separator && !items[i].disabled) { + if (i < 0 || i >= items.size()) + continue; - mouse_over = i; - update(); - break; - } - } - } break; + if (!items[i].separator && !items[i].disabled) { - case KEY_LEFT: { + mouse_over = i; + emit_signal("id_focused", i); + update(); + accept_event(); + break; + } + } + } else if (p_event->is_action("ui_up") && p_event->is_pressed()) { - Node *n = get_parent(); - if (!n) - break; + int search_from = mouse_over - 1; + if (search_from < 0) + search_from = items.size() - 1; - PopupMenu *pm = Object::cast_to<PopupMenu>(n); - if (!pm) - break; + for (int i = search_from; i >= 0; i--) { - hide(); - } break; + if (i < 0 || i >= items.size()) + continue; - case KEY_RIGHT: { + if (!items[i].separator && !items[i].disabled) { - if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && items[mouse_over].submenu != "" && submenu_over != mouse_over) - _activate_submenu(mouse_over); - } break; + mouse_over = i; + emit_signal("id_focused", i); + update(); + accept_event(); + break; + } + } + } else if (p_event->is_action("ui_left") && p_event->is_pressed()) { - case KEY_ENTER: - case KEY_KP_ENTER: { + Node *n = get_parent(); + if (n && Object::cast_to<PopupMenu>(n)) { + hide(); + accept_event(); + } + } else if (p_event->is_action("ui_right") && p_event->is_pressed()) { - if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) { + if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && items[mouse_over].submenu != "" && submenu_over != mouse_over) { + _activate_submenu(mouse_over); + accept_event(); + } + } else if (p_event->is_action("ui_accept") && p_event->is_pressed()) { - if (items[mouse_over].submenu != "" && submenu_over != mouse_over) { - _activate_submenu(mouse_over); - break; - } + if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) { - activate_item(mouse_over); - } - } break; + if (items[mouse_over].submenu != "" && submenu_over != mouse_over) { + _activate_submenu(mouse_over); + } else { + activate_item(mouse_over); + } + accept_event(); } } @@ -301,7 +284,8 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) { if (b->is_pressed()) return; - switch (b->get_button_index()) { + int button_idx = b->get_button_index(); + switch (button_idx) { case BUTTON_WHEEL_DOWN: { @@ -315,30 +299,37 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) { _scroll(b->get_factor(), b->get_position()); } } break; - case BUTTON_LEFT: { + default: { + // Allow activating item by releasing the LMB or any that was down when the popup appeared + if (button_idx == BUTTON_LEFT || (initial_button_mask & (1 << (button_idx - 1)))) { - int over = _get_mouse_over(b->get_position()); + bool was_during_grabbed_click = during_grabbed_click; + during_grabbed_click = false; - if (invalidated_click) { - invalidated_click = false; - break; - } - if (over < 0) { - hide(); - break; //non-activable - } + int over = _get_mouse_over(b->get_position()); - if (items[over].separator || items[over].disabled) - break; + if (invalidated_click) { + invalidated_click = false; + break; + } + if (over < 0) { + if (!was_during_grabbed_click) { + hide(); + } + break; //non-activable + } - if (items[over].submenu != "") { + if (items[over].separator || items[over].disabled) + break; - _activate_submenu(over); - return; - } - activate_item(over); + if (items[over].submenu != "") { - } break; + _activate_submenu(over); + return; + } + activate_item(over); + } + } } //update(); @@ -425,8 +416,9 @@ void PopupMenu::_notification(int p_what) { Ref<StyleBox> style = get_stylebox("panel"); Ref<StyleBox> hover = get_stylebox("hover"); Ref<Font> font = get_font("font"); - Ref<Texture> check = get_icon("checked"); - Ref<Texture> uncheck = get_icon("unchecked"); + // In Item::checkable_type enum order (less the non-checkable member) + Ref<Texture> check[] = { get_icon("checked"), get_icon("radio_checked") }; + Ref<Texture> uncheck[] = { get_icon("unchecked"), get_icon("radio_unchecked") }; Ref<Texture> submenu = get_icon("submenu"); Ref<StyleBox> separator = get_stylebox("separator"); @@ -469,14 +461,10 @@ void PopupMenu::_notification(int p_what) { separator->draw(ci, Rect2(item_ofs + Point2(0, Math::floor((h - sep_h) / 2.0)), Size2(get_size().width - style->get_minimum_size().width, sep_h))); } - if (items[i].checkable) { - - if (items[i].checked) - check->draw(ci, item_ofs + Point2(0, Math::floor((h - check->get_height()) / 2.0))); - else - uncheck->draw(ci, item_ofs + Point2(0, Math::floor((h - check->get_height()) / 2.0))); - - item_ofs.x += check->get_width() + hseparation; + if (items[i].checkable_type) { + Texture *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr(); + icon->draw(ci, item_ofs + Point2(0, Math::floor((h - icon->get_height()) / 2.0))); + item_ofs.x += icon->get_width() + hseparation; } if (!items[i].icon.is_null()) { @@ -520,6 +508,11 @@ void PopupMenu::_notification(int p_what) { update(); } } break; + case NOTIFICATION_POST_POPUP: { + + initial_button_mask = Input::get_singleton()->get_mouse_button_mask(); + during_grabbed_click = (bool)initial_button_mask; + } break; case NOTIFICATION_POPUP_HIDE: { if (mouse_over >= 0) { @@ -571,10 +564,11 @@ void PopupMenu::add_icon_check_item(const Ref<Texture> &p_icon, const String &p_ item.xl_text = tr(p_label); item.accel = p_accel; item.ID = p_ID; - item.checkable = true; + item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX; items.push_back(item); update(); } + void PopupMenu::add_check_item(const String &p_label, int p_ID, uint32_t p_accel) { Item item; @@ -582,11 +576,18 @@ void PopupMenu::add_check_item(const String &p_label, int p_ID, uint32_t p_accel item.xl_text = tr(p_label); item.accel = p_accel; item.ID = p_ID; - item.checkable = true; + item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX; items.push_back(item); update(); } +void PopupMenu::add_radio_check_item(const String &p_label, int p_ID, uint32_t p_accel) { + + add_check_item(p_label, p_ID, p_accel); + items[items.size() - 1].checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON; + update(); +} + void PopupMenu::add_icon_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_ID, bool p_global) { ERR_FAIL_COND(p_shortcut.is_null()); @@ -615,6 +616,7 @@ void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID, bool p_g items.push_back(item); update(); } + void PopupMenu::add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_ID, bool p_global) { ERR_FAIL_COND(p_shortcut.is_null()); @@ -624,7 +626,7 @@ void PopupMenu::add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<Sh Item item; item.ID = p_ID; item.shortcut = p_shortcut; - item.checkable = true; + item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX; item.icon = p_icon; item.shortcut_is_global = p_global; items.push_back(item); @@ -641,11 +643,18 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID, bo item.ID = p_ID; item.shortcut = p_shortcut; item.shortcut_is_global = p_global; - item.checkable = true; + item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX; items.push_back(item); update(); } +void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID, bool p_global) { + + add_check_shortcut(p_shortcut, p_ID, p_global); + items[items.size() - 1].checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON; + update(); +} + void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int p_default_state, int p_ID, uint32_t p_accel) { Item item; @@ -653,7 +662,6 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int item.xl_text = tr(p_label); item.accel = p_accel; item.ID = p_ID; - item.checkable = false; item.max_states = p_max_states; item.state = p_default_state; items.push_back(item); @@ -828,7 +836,14 @@ bool PopupMenu::is_item_separator(int p_idx) const { void PopupMenu::set_item_as_checkable(int p_idx, bool p_checkable) { ERR_FAIL_INDEX(p_idx, items.size()); - items[p_idx].checkable = p_checkable; + items[p_idx].checkable_type = p_checkable ? Item::CHECKABLE_TYPE_CHECK_BOX : Item::CHECKABLE_TYPE_NONE; + update(); +} + +void PopupMenu::set_item_as_radio_checkable(int p_idx, bool p_radio_checkable) { + + ERR_FAIL_INDEX(p_idx, items.size()); + items[p_idx].checkable_type = p_radio_checkable ? Item::CHECKABLE_TYPE_RADIO_BUTTON : Item::CHECKABLE_TYPE_NONE; update(); } @@ -884,7 +899,12 @@ void PopupMenu::toggle_item_multistate(int p_idx) { bool PopupMenu::is_item_checkable(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, items.size(), false); - return items[p_idx].checkable; + return items[p_idx].checkable_type; +} + +bool PopupMenu::is_item_radio_checkable(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, items.size(), false); + return items[p_idx].checkable_type == Item::CHECKABLE_TYPE_RADIO_BUTTON; } int PopupMenu::get_item_count() const { @@ -958,7 +978,7 @@ void PopupMenu::activate_item(int p_item) { // We close all parents that are chained together, // with hide_on_item_selection enabled - if (items[p_item].checkable) { + if (items[p_item].checkable_type) { if (!hide_on_checkable_item_selection || !pop->is_hide_on_checkable_item_selection()) break; } else if (0 < items[p_item].max_states) { @@ -975,7 +995,7 @@ void PopupMenu::activate_item(int p_item) { // Hides popup by default; unless otherwise specified // by using set_hide_on_item_selection and set_hide_on_checkable_item_selection - if (items[p_item].checkable) { + if (items[p_item].checkable_type) { if (!hide_on_checkable_item_selection) return; } else if (0 < items[p_item].max_states) { @@ -1027,7 +1047,9 @@ Array PopupMenu::_get_items() const { items.push_back(get_item_text(i)); items.push_back(get_item_icon(i)); - items.push_back(is_item_checkable(i)); + // For compatibility, use false/true for no/checkbox and integers for other values + int ct = this->items[i].checkable_type; + items.push_back(Variant(ct <= Item::CHECKABLE_TYPE_CHECK_BOX ? is_item_checkable(i) : ct)); items.push_back(is_item_checked(i)); items.push_back(is_item_disabled(i)); @@ -1070,7 +1092,9 @@ void PopupMenu::_set_items(const Array &p_items) { String text = p_items[i + 0]; Ref<Texture> icon = p_items[i + 1]; + // For compatibility, use false/true for no/checkbox and integers for other values bool checkable = p_items[i + 2]; + bool radio_checkable = (int)p_items[i + 2] == Item::CHECKABLE_TYPE_RADIO_BUTTON; bool checked = p_items[i + 3]; bool disabled = p_items[i + 4]; @@ -1083,7 +1107,13 @@ void PopupMenu::_set_items(const Array &p_items) { int idx = get_item_count(); add_item(text, id); set_item_icon(idx, icon); - set_item_as_checkable(idx, checkable); + if (checkable) { + if (radio_checkable) { + set_item_as_radio_checkable(idx, true); + } else { + set_item_as_checkable(idx, true); + } + } set_item_checked(idx, checked); set_item_disabled(idx, disabled); set_item_id(idx, id); @@ -1164,12 +1194,14 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("add_item", "label", "id", "accel"), &PopupMenu::add_item, DEFVAL(-1), DEFVAL(0)); ClassDB::bind_method(D_METHOD("add_icon_check_item", "texture", "label", "id", "accel"), &PopupMenu::add_icon_check_item, DEFVAL(-1), DEFVAL(0)); ClassDB::bind_method(D_METHOD("add_check_item", "label", "id", "accel"), &PopupMenu::add_check_item, DEFVAL(-1), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("add_radio_check_item", "label", "id", "accel"), &PopupMenu::add_radio_check_item, DEFVAL(-1), DEFVAL(0)); ClassDB::bind_method(D_METHOD("add_submenu_item", "label", "submenu", "id"), &PopupMenu::add_submenu_item, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("add_icon_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::add_icon_shortcut, DEFVAL(-1), DEFVAL(false)); ClassDB::bind_method(D_METHOD("add_shortcut", "shortcut", "id", "global"), &PopupMenu::add_shortcut, DEFVAL(-1), DEFVAL(false)); ClassDB::bind_method(D_METHOD("add_icon_check_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::add_icon_check_shortcut, DEFVAL(-1), DEFVAL(false)); ClassDB::bind_method(D_METHOD("add_check_shortcut", "shortcut", "id", "global"), &PopupMenu::add_check_shortcut, DEFVAL(-1), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_radio_check_shortcut", "shortcut", "id", "global"), &PopupMenu::add_radio_check_shortcut, DEFVAL(-1), DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_item_text", "idx", "text"), &PopupMenu::set_item_text); ClassDB::bind_method(D_METHOD("set_item_icon", "idx", "icon"), &PopupMenu::set_item_icon); @@ -1181,6 +1213,7 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_submenu", "idx", "submenu"), &PopupMenu::set_item_submenu); ClassDB::bind_method(D_METHOD("set_item_as_separator", "idx", "enable"), &PopupMenu::set_item_as_separator); ClassDB::bind_method(D_METHOD("set_item_as_checkable", "idx", "enable"), &PopupMenu::set_item_as_checkable); + ClassDB::bind_method(D_METHOD("set_item_as_radio_checkable", "idx", "enable"), &PopupMenu::set_item_as_radio_checkable); ClassDB::bind_method(D_METHOD("set_item_tooltip", "idx", "tooltip"), &PopupMenu::set_item_tooltip); ClassDB::bind_method(D_METHOD("set_item_shortcut", "idx", "shortcut", "global"), &PopupMenu::set_item_shortcut, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_item_multistate", "idx", "state"), &PopupMenu::set_item_multistate); @@ -1199,6 +1232,7 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_submenu", "idx"), &PopupMenu::get_item_submenu); ClassDB::bind_method(D_METHOD("is_item_separator", "idx"), &PopupMenu::is_item_separator); ClassDB::bind_method(D_METHOD("is_item_checkable", "idx"), &PopupMenu::is_item_checkable); + ClassDB::bind_method(D_METHOD("is_item_radio_checkable", "idx"), &PopupMenu::is_item_radio_checkable); ClassDB::bind_method(D_METHOD("get_item_tooltip", "idx"), &PopupMenu::get_item_tooltip); ClassDB::bind_method(D_METHOD("get_item_shortcut", "idx"), &PopupMenu::get_item_shortcut); @@ -1229,18 +1263,24 @@ void PopupMenu::_bind_methods() { ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "hide_on_state_item_selection"), "set_hide_on_state_item_selection", "is_hide_on_state_item_selection"); ADD_SIGNAL(MethodInfo("id_pressed", PropertyInfo(Variant::INT, "ID"))); + ADD_SIGNAL(MethodInfo("id_focused", PropertyInfo(Variant::INT, "ID"))); ADD_SIGNAL(MethodInfo("index_pressed", PropertyInfo(Variant::INT, "index"))); } -void PopupMenu::set_invalidate_click_until_motion() { +void PopupMenu::popup(const Rect2 &p_bounds) { + + grab_click_focus(); moved = Vector2(); invalidated_click = true; + Popup::popup(p_bounds); } PopupMenu::PopupMenu() { mouse_over = -1; submenu_over = -1; + initial_button_mask = 0; + during_grabbed_click = false; set_focus_mode(FOCUS_ALL); set_as_toplevel(true); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 60f36e95ec..c7851969d0 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -46,7 +46,11 @@ class PopupMenu : public Popup { String text; String xl_text; bool checked; - bool checkable; + enum { + CHECKABLE_TYPE_NONE, + CHECKABLE_TYPE_CHECK_BOX, + CHECKABLE_TYPE_RADIO_BUTTON, + } checkable_type; int max_states; int state; bool separator; @@ -63,7 +67,7 @@ class PopupMenu : public Popup { Item() { checked = false; - checkable = false; + checkable_type = CHECKABLE_TYPE_NONE; separator = false; max_states = 0; state = 0; @@ -78,6 +82,8 @@ class PopupMenu : public Popup { Timer *submenu_timer; List<Rect2> autohide_areas; Vector<Item> items; + int initial_button_mask; + bool during_grabbed_click; int mouse_over; int submenu_over; Rect2 parent_rect; @@ -115,12 +121,14 @@ public: void add_item(const String &p_label, int p_ID = -1, uint32_t p_accel = 0); void add_icon_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_ID = -1, uint32_t p_accel = 0); void add_check_item(const String &p_label, int p_ID = -1, uint32_t p_accel = 0); + void add_radio_check_item(const String &p_label, int p_ID = -1, uint32_t p_accel = 0); void add_submenu_item(const String &p_label, const String &p_submenu, int p_ID = -1); void add_icon_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_ID = -1, bool p_global = false); void add_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID = -1, bool p_global = false); void add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_ID = -1, bool p_global = false); void add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID = -1, bool p_global = false); + void add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ID = -1, bool p_global = false); void add_multistate_item(const String &p_label, int p_max_states, int p_default_state, int p_ID = -1, uint32_t p_accel = 0); @@ -134,6 +142,7 @@ public: void set_item_submenu(int p_idx, const String &p_submenu); void set_item_as_separator(int p_idx, bool p_separator); void set_item_as_checkable(int p_idx, bool p_checkable); + void set_item_as_radio_checkable(int p_idx, bool p_radio_checkable); void set_item_tooltip(int p_idx, const String &p_tooltip); void set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bool p_global = false); void set_item_h_offset(int p_idx, int p_offset); @@ -154,6 +163,7 @@ public: String get_item_submenu(int p_idx) const; bool is_item_separator(int p_idx) const; bool is_item_checkable(int p_idx) const; + bool is_item_radio_checkable(int p_idx) const; String get_item_tooltip(int p_idx) const; Ref<ShortCut> get_item_shortcut(int p_idx) const; int get_item_state(int p_idx) const; @@ -178,7 +188,6 @@ public: void add_autohide_area(const Rect2 &p_area); void clear_autohide_areas(); - void set_invalidate_click_until_motion(); void set_hide_on_item_selection(bool p_enabled); bool is_hide_on_item_selection() const; @@ -188,6 +197,8 @@ public: void set_hide_on_multistate_item_selection(bool p_enabled); bool is_hide_on_multistate_item_selection() const; + virtual void popup(const Rect2 &p_bounds = Rect2()); + PopupMenu(); ~PopupMenu(); }; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 381c6c75a5..6bfc4d4dee 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -125,6 +125,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & l.descent_caches.clear(); l.char_count = 0; l.minimum_width = 0; + l.maximum_width = 0; } int wofs = margin; @@ -200,7 +201,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & #define ENSURE_WIDTH(m_width) \ if (p_mode == PROCESS_CACHE) { \ - l.minimum_width = MAX(l.minimum_width, wofs + m_width); \ + l.maximum_width = MAX(l.maximum_width, MIN(p_width, wofs + m_width)); \ + l.minimum_width = MAX(l.minimum_width, m_width); \ } \ if (wofs + m_width > p_width) { \ if (p_mode == PROCESS_CACHE) { \ @@ -247,6 +249,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & int rchar = 0; int lh = 0; bool line_is_blank = true; + int fh = 0; while (it) { @@ -262,14 +265,9 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & const CharType *c = text->text.c_str(); const CharType *cf = c; - int fh = font->get_height(); int ascent = font->get_ascent(); int descent = font->get_descent(); - line_ascent = MAX(line_ascent, ascent); - line_descent = MAX(line_descent, descent); - fh = MAX(fh, line_ascent + line_descent); // various fonts! - Color color; bool underline = false; @@ -317,8 +315,13 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & end++; } + CHECK_HEIGHT(fh); ENSURE_WIDTH(w); + line_ascent = MAX(line_ascent, ascent); + line_descent = MAX(line_descent, descent); + fh = line_ascent + line_descent; + if (end && c[end - 1] == ' ') { if (p_mode == PROCESS_CACHE) { spaces_size += font->get_char_size(' ').width; @@ -468,6 +471,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & //set minimums to zero for (int i = 0; i < table->columns.size(); i++) { table->columns[i].min_width = 0; + table->columns[i].max_width = 0; table->columns[i].width = 0; } //compute minimum width for each cell @@ -485,6 +489,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & _process_line(frame, Point2(), ly, available_width, i, PROCESS_CACHE, cfont, Color()); table->columns[column].min_width = MAX(table->columns[column].min_width, frame->lines[i].minimum_width); + table->columns[column].max_width = MAX(table->columns[column].max_width, frame->lines[i].maximum_width); } idx++; } @@ -497,12 +502,13 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & for (int i = 0; i < table->columns.size(); i++) { remaining_width -= table->columns[i].min_width; + if (table->columns[i].max_width > table->columns[i].min_width) + table->columns[i].expand = true; if (table->columns[i].expand) total_ratio += table->columns[i].expand_ratio; } //assign actual widths - for (int i = 0; i < table->columns.size(); i++) { table->columns[i].width = table->columns[i].min_width; if (table->columns[i].expand) @@ -510,6 +516,39 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & table->total_width += table->columns[i].width + hseparation; } + //resize to max_width if needed and distribute the remaining space + bool table_need_fit = true; + while (table_need_fit) { + table_need_fit = false; + //fit slim + for (int i = 0; i < table->columns.size(); i++) { + if (!table->columns[i].expand) + continue; + int dif = table->columns[i].width - table->columns[i].max_width; + if (dif > 0) { + table_need_fit = true; + table->columns[i].width = table->columns[i].max_width; + table->total_width -= dif; + total_ratio -= table->columns[i].expand_ratio; + } + } + //grow + remaining_width = available_width - table->total_width; + if (remaining_width > 0 && total_ratio > 0) { + for (int i = 0; i < table->columns.size(); i++) { + if (table->columns[i].expand) { + int dif = table->columns[i].max_width - table->columns[i].width; + if (dif > 0) { + int slice = table->columns[i].expand_ratio * remaining_width / total_ratio; + int incr = MIN(dif, slice); + table->columns[i].width += incr; + table->total_width += incr; + } + } + } + } + } + //compute caches properly again with the right width idx = 0; for (List<Item *>::Element *E = table->subitems.front(); E; E = E->next()) { @@ -1632,7 +1671,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { tag_stack.push_front(tag); } else if (tag.begins_with("cell=")) { - int ratio = tag.substr(6, tag.length()).to_int(); + int ratio = tag.substr(5, tag.length()).to_int(); if (ratio < 1) ratio = 1; //use monospace font diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index e7d5e6bb1b..83938cff61 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -87,6 +87,7 @@ private: int height_accum_cache; int char_count; int minimum_width; + int maximum_width; Line() { from = NULL; @@ -199,6 +200,7 @@ private: bool expand; int expand_ratio; int min_width; + int max_width; int width; }; diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 95fcda2db3..e1cabd3f88 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -199,54 +199,40 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) { } } - Ref<InputEventKey> k = p_event; + if (p_event->is_pressed()) { - if (k.is_valid()) { + if (p_event->is_action("ui_left")) { - if (!k->is_pressed()) - return; - - switch (k->get_scancode()) { - - case KEY_LEFT: { - - if (orientation != HORIZONTAL) - return; - set_value(get_value() - (custom_step >= 0 ? custom_step : get_step())); + if (orientation != HORIZONTAL) + return; + set_value(get_value() - (custom_step >= 0 ? custom_step : get_step())); - } break; - case KEY_RIGHT: { + } else if (p_event->is_action("ui_right")) { - if (orientation != HORIZONTAL) - return; - set_value(get_value() + (custom_step >= 0 ? custom_step : get_step())); - - } break; - case KEY_UP: { + if (orientation != HORIZONTAL) + return; + set_value(get_value() + (custom_step >= 0 ? custom_step : get_step())); - if (orientation != VERTICAL) - return; + } else if (p_event->is_action("ui_up")) { - set_value(get_value() - (custom_step >= 0 ? custom_step : get_step())); + if (orientation != VERTICAL) + return; - } break; - case KEY_DOWN: { + set_value(get_value() - (custom_step >= 0 ? custom_step : get_step())); - if (orientation != VERTICAL) - return; - set_value(get_value() + (custom_step >= 0 ? custom_step : get_step())); + } else if (p_event->is_action("ui_down")) { - } break; - case KEY_HOME: { + if (orientation != VERTICAL) + return; + set_value(get_value() + (custom_step >= 0 ? custom_step : get_step())); - set_value(get_min()); + } else if (p_event->is_action("ui_home")) { - } break; - case KEY_END: { + set_value(get_min()); - set_value(get_max()); + } else if (p_event->is_action("ui_end")) { - } break; + set_value(get_max()); } } } diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index a7a1b499c3..46215c9277 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -118,28 +118,14 @@ void Slider::_gui_input(Ref<InputEvent> p_event) { return; set_value(get_value() - (custom_step >= 0 ? custom_step : get_step())); accept_event(); + } else if (p_event->is_action("ui_home") && p_event->is_pressed()) { - } else { - - Ref<InputEventKey> k = p_event; - - if (!k.is_valid() || !k->is_pressed()) - return; - - switch (k->get_scancode()) { - - case KEY_HOME: { - - set_value(get_min()); - accept_event(); - } break; - case KEY_END: { - - set_value(get_max()); - accept_event(); + set_value(get_min()); + accept_event(); + } else if (p_event->is_action("ui_end") && p_event->is_pressed()) { - } break; - } + set_value(get_max()); + accept_event(); } } } diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index f0e89877cd..dee32aef7a 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -882,4 +882,6 @@ Tabs::Tabs() { min_width = 0; scrolling_enabled = true; + buttons_visible = false; + hover = -1; } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index f13950461b..e214a020d5 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -145,6 +145,7 @@ void TextEdit::Text::_update_line_cache(int p_line) const { text[p_line].region_info.clear(); + int ending_color_region = -1; for (int i = 0; i < len; i++) { if (!_is_symbol(str[i])) @@ -184,6 +185,12 @@ void TextEdit::Text::_update_line_cache(int p_line) const { cri.region = j; text[p_line].region_info[i] = cri; i += lr - 1; + + if (ending_color_region == -1 && !cr.line_only) { + ending_color_region = j; + } else if (ending_color_region == j) { + ending_color_region = -1; + } break; } @@ -211,10 +218,16 @@ void TextEdit::Text::_update_line_cache(int p_line) const { cri.region = j; text[p_line].region_info[i] = cri; i += lr - 1; + + if (ending_color_region == j) { + ending_color_region = -1; + } + break; } } } + text[p_line].ending_color_region = ending_color_region; } const Map<int, TextEdit::Text::ColorRegionInfo> &TextEdit::Text::get_color_region_info(int p_line) const { @@ -619,44 +632,10 @@ void TextEdit::_notification(int p_what) { Color color = cache.font_color; color.a *= readonly_alpha; - int in_region = -1; - if (syntax_coloring) { - if (cache.background_color.a > 0.01) { - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(), get_size()), cache.background_color); } - //compute actual region to start (may be inside say, a comment). - //slow in very large documments :( but ok for source! - - for (int i = 0; i < cursor.line_ofs; i++) { - - const Map<int, Text::ColorRegionInfo> &cri_map = text.get_color_region_info(i); - - if (in_region >= 0 && color_regions[in_region].line_only) { - in_region = -1; //reset regions that end at end of line - } - - for (const Map<int, Text::ColorRegionInfo>::Element *E = cri_map.front(); E; E = E->next()) { - - const Text::ColorRegionInfo &cri = E->get(); - - if (in_region == -1) { - - if (!cri.end) { - - in_region = cri.region; - } - } else if (in_region == cri.region && !color_regions[cri.region].line_only) { //ignore otherwise - - if (cri.end || color_regions[cri.region].eq) { - - in_region = -1; - } - } - } - } } int brace_open_match_line = -1; @@ -804,7 +783,6 @@ void TextEdit::_notification(int p_what) { } } - int deregion = 0; //force it to clear inrgion Point2 cursor_pos; // get the highlighted words @@ -848,19 +826,12 @@ void TextEdit::_notification(int p_what) { if (smooth_scroll_enabled) ofs_y -= ((v_scroll->get_value() - get_line_scroll_pos()) * get_row_height()); - bool prev_is_char = false; - bool prev_is_number = false; - bool in_keyword = false; bool underlined = false; - bool in_word = false; - bool in_function_name = false; - bool in_member_variable = false; - bool is_hex_notation = false; - Color keyword_color; // check if line contains highlighted word int highlighted_text_col = -1; int search_text_col = -1; + int highlighted_word_col = -1; if (!search_text.empty()) search_text_col = _get_column_pos_of_word(search_text, str, search_flags, 0); @@ -868,7 +839,11 @@ void TextEdit::_notification(int p_what) { if (highlighted_text.length() != 0 && highlighted_text != search_text) highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0); - const Map<int, Text::ColorRegionInfo> &cri_map = text.get_color_region_info(line); + if (select_identifiers_enabled && highlighted_word.length() != 0) { + if (_is_char(highlighted_word[0])) { + highlighted_word_col = _get_column_pos_of_word(highlighted_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0); + } + } if (text.is_marked(line)) { @@ -936,170 +911,28 @@ void TextEdit::_notification(int p_what) { cache.font->draw(ci, Point2(cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width + ofs_x, ofs_y + cache.font->get_ascent()), fc, cache.line_number_color); } - //loop through characters in one line - for (int j = 0; j < str.length(); j++) { - - //look for keyword - - if (deregion > 0) { - deregion--; - if (deregion == 0) - in_region = -1; - } - if (syntax_coloring && deregion == 0) { - - color = cache.font_color; //reset - color.a *= readonly_alpha; - //find keyword - bool is_char = _is_text_char(str[j]); - bool is_symbol = _is_symbol(str[j]); - bool is_number = _is_number(str[j]); - - if (j == 0 && in_region >= 0 && color_regions[in_region].line_only) { - in_region = -1; //reset regions that end at end of line - } - - // allow ABCDEF in hex notation - if (is_hex_notation && (_is_hex_symbol(str[j]) || is_number)) { - is_number = true; - } else { - is_hex_notation = false; - } - - // check for dot or underscore or 'x' for hex notation in floating point number - if ((str[j] == '.' || str[j] == 'x' || str[j] == '_') && !in_word && prev_is_number && !is_number) { - is_number = true; - is_symbol = false; - is_char = false; - - if (str[j] == 'x' && str[j - 1] == '0') { - is_hex_notation = true; - } - } - - if (!in_word && _is_char(str[j]) && !is_number) { - in_word = true; - } - - if ((in_keyword || in_word) && !is_hex_notation) { - is_number = false; - } - - if (is_symbol && str[j] != '.' && in_word) { - in_word = false; - } - - if (is_symbol && cri_map.has(j)) { - - const Text::ColorRegionInfo &cri = cri_map[j]; - - if (in_region == -1) { - - if (!cri.end) { - - in_region = cri.region; - } - } else if (in_region == cri.region && !color_regions[cri.region].line_only) { //ignore otherwise - - if (cri.end || color_regions[cri.region].eq) { - deregion = color_regions[cri.region].eq ? color_regions[cri.region].begin_key.length() : color_regions[cri.region].end_key.length(); - } - } - } - - if (!is_char) { - in_keyword = false; - underlined = false; - } - - if (in_region == -1 && !in_keyword && is_char && !prev_is_char) { - - int to = j; - while (to < str.length() && _is_text_char(str[to])) - to++; - - uint32_t hash = String::hash(&str[j], to - j); - StrRange range(&str[j], to - j); - - const Color *col = keywords.custom_getptr(range, hash); - - if (!col) { - col = member_keywords.custom_getptr(range, hash); - - if (col) { - for (int k = j - 1; k >= 0; k--) { - if (str[k] == '.') { - col = NULL; //member indexing not allowed - break; - } else if (str[k] > 32) { - break; - } - } - } - } - - if (col) { - - in_keyword = true; - keyword_color = *col; - } - - if (select_identifiers_enabled && highlighted_word != String()) { - if (highlighted_word == range) { - underlined = true; - } - } - } - - if (!in_function_name && in_word && !in_keyword) { - - int k = j; - while (k < str.length() && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { - k++; - } - - // check for space between name and bracket - while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) { - k++; - } - - if (str[k] == '(') { - in_function_name = true; - } - } + //loop through characters in one line + Map<int, HighlighterInfo> color_map; + if (syntax_coloring) { + color_map = _get_line_syntax_highlighting(line); + } - if (!in_function_name && !in_member_variable && !in_keyword && !is_number && in_word) { - int k = j; - while (k > 0 && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { - k--; - } + // ensure we at least use the font color + Color current_color = cache.font_color; + if (readonly) { + current_color.a *= readonly_alpha; + } + for (int j = 0; j < str.length(); j++) { - if (str[k] == '.') { - in_member_variable = true; + if (syntax_coloring) { + if (color_map.has(j)) { + current_color = color_map[j].color; + if (readonly) { + current_color.a *= readonly_alpha; } } - - if (is_symbol) { - in_function_name = false; - in_member_variable = false; - } - - if (in_region >= 0) - color = color_regions[in_region].color; - else if (in_keyword) - color = keyword_color; - else if (in_member_variable) - color = cache.member_variable_color; - else if (in_function_name) - color = cache.function_color; - else if (is_symbol) - color = cache.symbol_color; - else if (is_number) - color = cache.number_color; - - prev_is_char = is_char; - prev_is_number = is_number; + color = current_color; } int char_w; @@ -1206,6 +1039,13 @@ void TextEdit::_notification(int p_what) { } } + if (highlighted_word_col != -1) { + if (j > highlighted_word_col + highlighted_word.length()) { + highlighted_word_col = _get_column_pos_of_word(highlighted_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, j); + } + underlined = (j >= highlighted_word_col && j < highlighted_word_col + highlighted_word.length()); + } + if (brace_matching_enabled) { if ((brace_open_match_line == line && brace_open_match_column == j) || (cursor.column == j && cursor.line == line && (brace_open_matching || brace_open_mismatch))) { @@ -1512,6 +1352,7 @@ void TextEdit::_notification(int p_what) { OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos + Point2(0, get_row_height())); OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this); } + } break; case NOTIFICATION_FOCUS_ENTER: { @@ -1528,7 +1369,6 @@ void TextEdit::_notification(int p_what) { if (raised_from_completion) { VisualServer::get_singleton()->canvas_item_set_z_index(get_canvas_item(), 1); } - } break; case NOTIFICATION_FOCUS_EXIT: { @@ -2141,9 +1981,12 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (completion_index > 0) { completion_index--; - completion_current = completion_options[completion_index]; - update(); + } else { + completion_index = completion_options.size() - 1; } + completion_current = completion_options[completion_index]; + update(); + accept_event(); return; } @@ -2152,9 +1995,12 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (completion_index < completion_options.size() - 1) { completion_index++; - completion_current = completion_options[completion_index]; - update(); + } else { + completion_index = 0; } + completion_current = completion_options[completion_index]; + update(); + accept_event(); return; } @@ -4144,6 +3990,44 @@ void TextEdit::_update_caches() { cache.can_fold_icon = get_icon("GuiTreeArrowDown", "EditorIcons"); cache.folded_eol_icon = get_icon("GuiEllipsis", "EditorIcons"); text.set_font(cache.font); + + if (syntax_highlighter) { + syntax_highlighter->_update_cache(); + } +} + +SyntaxHighlighter *TextEdit::_get_syntax_highlighting() { + return syntax_highlighter; +} + +void TextEdit::_set_syntax_highlighting(SyntaxHighlighter *p_syntax_highlighter) { + syntax_highlighter = p_syntax_highlighter; + if (syntax_highlighter) { + syntax_highlighter->set_text_editor(this); + syntax_highlighter->_update_cache(); + } + update(); +} + +int TextEdit::_get_line_ending_color_region(int p_line) const { + if (p_line < 0 || p_line > text.size() - 1) { + return -1; + } + return text.get_line_ending_color_region(p_line); +} + +TextEdit::ColorRegion TextEdit::_get_color_region(int p_region) const { + if (p_region < 0 || p_region > color_regions.size()) { + return ColorRegion(); + } + return color_regions[p_region]; +} + +Map<int, TextEdit::Text::ColorRegionInfo> TextEdit::_get_line_color_region_info(int p_line) const { + if (p_line < 0 || p_line > text.size() - 1) { + return Map<int, Text::ColorRegionInfo>(); + } + return text.get_color_region_info(p_line); } void TextEdit::clear_colors() { @@ -4159,6 +4043,14 @@ void TextEdit::add_keyword_color(const String &p_keyword, const Color &p_color) update(); } +bool TextEdit::has_keyword_color(String p_keyword) const { + return keywords.has(p_keyword); +} + +Color TextEdit::get_keyword_color(String p_keyword) const { + return keywords[p_keyword]; +} + void TextEdit::add_color_region(const String &p_begin_key, const String &p_end_key, const Color &p_color, bool p_line_only) { color_regions.push_back(ColorRegion(p_begin_key, p_end_key, p_color, p_line_only)); @@ -4171,6 +4063,14 @@ void TextEdit::add_member_keyword(const String &p_keyword, const Color &p_color) update(); } +bool TextEdit::has_member_color(String p_member) const { + return member_keywords.has(p_member); +} + +Color TextEdit::get_member_color(String p_member) const { + return member_keywords[p_member]; +} + void TextEdit::clear_member_keywords() { member_keywords.clear(); update(); @@ -4470,7 +4370,7 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l ERR_FAIL_INDEX_V(p_from_line, text.size(), false); ERR_FAIL_INDEX_V(p_from_column, text[p_from_line].length() + 1, false); - //search through the whole documment, but start by current line + //search through the whole document, but start by current line int line = p_from_line; int pos = -1; @@ -5232,7 +5132,7 @@ void TextEdit::_update_completion_candidates() { } else { - while (cofs > 0 && l[cofs - 1] > 32 && _is_completable(l[cofs - 1])) { + while (cofs > 0 && l[cofs - 1] > 32 && (l[cofs - 1] == '/' || _is_completable(l[cofs - 1]))) { s = String::chr(l[cofs - 1]) + s; if (l[cofs - 1] == '\'' || l[cofs - 1] == '"' || l[cofs - 1] == '$') break; @@ -5685,6 +5585,8 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_v_scroll_speed"), &TextEdit::get_v_scroll_speed); ClassDB::bind_method(D_METHOD("add_keyword_color", "keyword", "color"), &TextEdit::add_keyword_color); + ClassDB::bind_method(D_METHOD("has_keyword_color", "keyword"), &TextEdit::has_keyword_color); + ClassDB::bind_method(D_METHOD("get_keyword_color", "keyword"), &TextEdit::get_keyword_color); ClassDB::bind_method(D_METHOD("add_color_region", "begin_key", "end_key", "color", "line_only"), &TextEdit::add_color_region, DEFVAL(false)); ClassDB::bind_method(D_METHOD("clear_colors"), &TextEdit::clear_colors); ClassDB::bind_method(D_METHOD("menu_option", "option"), &TextEdit::menu_option); @@ -5738,6 +5640,7 @@ TextEdit::TextEdit() { clear(); wrap = false; set_focus_mode(FOCUS_ALL); + syntax_highlighter = NULL; _update_caches(); cache.size = Size2(1, 1); cache.row_height = 1; @@ -5854,3 +5757,216 @@ TextEdit::TextEdit() { TextEdit::~TextEdit() { } + +/////////////////////////////////////////////////////////////////////////////// + +Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int p_line) { + if (syntax_highlighter != NULL) { + return syntax_highlighter->_get_line_syntax_highlighting(p_line); + } + + Map<int, HighlighterInfo> color_map; + + bool prev_is_char = false; + bool prev_is_number = false; + bool in_keyword = false; + bool in_word = false; + bool in_function_name = false; + bool in_member_variable = false; + bool is_hex_notation = false; + Color keyword_color; + Color color; + + int in_region = -1; + int deregion = 0; + for (int i = 0; i < p_line; i++) { + int ending_color_region = text.get_line_ending_color_region(i); + if (in_region == -1) { + in_region = ending_color_region; + } else if (in_region == ending_color_region) { + in_region = -1; + } else { + const Map<int, TextEdit::Text::ColorRegionInfo> &cri_map = text.get_color_region_info(i); + for (const Map<int, TextEdit::Text::ColorRegionInfo>::Element *E = cri_map.front(); E; E = E->next()) { + const TextEdit::Text::ColorRegionInfo &cri = E->get(); + if (cri.region == in_region) { + in_region = -1; + } + } + } + } + + const Map<int, TextEdit::Text::ColorRegionInfo> cri_map = text.get_color_region_info(p_line); + const String &str = text[p_line]; + Color prev_color; + for (int j = 0; j < str.length(); j++) { + HighlighterInfo highlighter_info; + + if (deregion > 0) { + deregion--; + if (deregion == 0) { + in_region = -1; + } + } + + if (deregion != 0) { + if (color != prev_color) { + prev_color = color; + highlighter_info.color = color; + color_map[j] = highlighter_info; + } + continue; + } + + color = cache.font_color; + + bool is_char = _is_text_char(str[j]); + bool is_symbol = _is_symbol(str[j]); + bool is_number = _is_number(str[j]); + + // allow ABCDEF in hex notation + if (is_hex_notation && (_is_hex_symbol(str[j]) || is_number)) { + is_number = true; + } else { + is_hex_notation = false; + } + + // check for dot or underscore or 'x' for hex notation in floating point number + if ((str[j] == '.' || str[j] == 'x' || str[j] == '_') && !in_word && prev_is_number && !is_number) { + is_number = true; + is_symbol = false; + is_char = false; + + if (str[j] == 'x' && str[j - 1] == '0') { + is_hex_notation = true; + } + } + + if (!in_word && _is_char(str[j]) && !is_number) { + in_word = true; + } + + if ((in_keyword || in_word) && !is_hex_notation) { + is_number = false; + } + + if (is_symbol && str[j] != '.' && in_word) { + in_word = false; + } + + if (is_symbol && cri_map.has(j)) { + const TextEdit::Text::ColorRegionInfo &cri = cri_map[j]; + + if (in_region == -1) { + if (!cri.end) { + in_region = cri.region; + } + } else if (in_region == cri.region && !color_regions[cri.region].line_only) { //ignore otherwise + if (cri.end || color_regions[cri.region].eq) { + deregion = color_regions[cri.region].eq ? color_regions[cri.region].begin_key.length() : color_regions[cri.region].end_key.length(); + } + } + } + + if (!is_char) { + in_keyword = false; + } + + if (in_region == -1 && !in_keyword && is_char && !prev_is_char) { + + int to = j; + while (to < str.length() && _is_text_char(str[to])) + to++; + + uint32_t hash = String::hash(&str[j], to - j); + StrRange range(&str[j], to - j); + + const Color *col = keywords.custom_getptr(range, hash); + + if (!col) { + col = member_keywords.custom_getptr(range, hash); + + if (col) { + for (int k = j - 1; k >= 0; k--) { + if (str[k] == '.') { + col = NULL; //member indexing not allowed + break; + } else if (str[k] > 32) { + break; + } + } + } + } + + if (col) { + in_keyword = true; + keyword_color = *col; + } + } + + if (!in_function_name && in_word && !in_keyword) { + + int k = j; + while (k < str.length() && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { + k++; + } + + // check for space between name and bracket + while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) { + k++; + } + + if (str[k] == '(') { + in_function_name = true; + } + } + + if (!in_function_name && !in_member_variable && !in_keyword && !is_number && in_word) { + int k = j; + while (k > 0 && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { + k--; + } + + if (str[k] == '.') { + in_member_variable = true; + } + } + + if (is_symbol) { + in_function_name = false; + in_member_variable = false; + } + + if (in_region >= 0) + color = color_regions[in_region].color; + else if (in_keyword) + color = keyword_color; + else if (in_member_variable) + color = cache.member_variable_color; + else if (in_function_name) + color = cache.function_color; + else if (is_symbol) + color = cache.symbol_color; + else if (is_number) + color = cache.number_color; + + prev_is_char = is_char; + prev_is_number = is_number; + + if (color != prev_color) { + prev_color = color; + highlighter_info.color = color; + color_map[j] = highlighter_info; + } + } + + return color_map; +} + +void SyntaxHighlighter::set_text_editor(TextEdit *p_text_editor) { + text_editor = p_text_editor; +} + +TextEdit *SyntaxHighlighter::get_text_editor() { + return text_editor; +} diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 8ac3b9fce6..2360ce79db 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -36,10 +36,84 @@ #include "scene/gui/scroll_bar.h" #include "scene/main/timer.h" +class SyntaxHighlighter; + class TextEdit : public Control { - GDCLASS(TextEdit, Control); + GDCLASS(TextEdit, Control) + +public: + struct HighlighterInfo { + Color color; + }; + + struct ColorRegion { + + Color color; + String begin_key; + String end_key; + bool line_only; + bool eq; + ColorRegion(const String &p_begin_key = "", const String &p_end_key = "", const Color &p_color = Color(), bool p_line_only = false) { + begin_key = p_begin_key; + end_key = p_end_key; + color = p_color; + line_only = p_line_only || p_end_key == ""; + eq = begin_key == end_key; + } + }; + + class Text { + public: + struct ColorRegionInfo { + + int region; + bool end; + }; + + struct Line { + int width_cache : 24; + bool marked : 1; + bool breakpoint : 1; + bool hidden : 1; + int ending_color_region; + Map<int, ColorRegionInfo> region_info; + String data; + }; + + private: + const Vector<ColorRegion> *color_regions; + mutable Vector<Line> text; + Ref<Font> font; + int indent_size; + + void _update_line_cache(int p_line) const; + + public: + void set_indent_size(int p_indent_size); + void set_font(const Ref<Font> &p_font); + void set_color_regions(const Vector<ColorRegion> *p_regions) { color_regions = p_regions; } + int get_line_width(int p_line) const; + int get_max_width(bool p_exclude_hidden = false) const; + const Map<int, ColorRegionInfo> &get_color_region_info(int p_line) const; + void set(int p_line, const String &p_text); + void set_marked(int p_line, bool p_marked) { text[p_line].marked = p_marked; } + bool is_marked(int p_line) const { return text[p_line].marked; } + void set_breakpoint(int p_line, bool p_breakpoint) { text[p_line].breakpoint = p_breakpoint; } + bool is_breakpoint(int p_line) const { return text[p_line].breakpoint; } + void set_hidden(int p_line, bool p_hidden) { text[p_line].hidden = p_hidden; } + bool is_hidden(int p_line) const { return text[p_line].hidden; } + int get_line_ending_color_region(int p_line) const { return text[p_line].ending_color_region; } + void insert(int p_at, const String &p_text); + void remove(int p_at); + int size() const { return text.size(); } + void clear(); + void clear_caches(); + _FORCE_INLINE_ const String &operator[](int p_line) const { return text[p_line].data; } + Text() { indent_size = 4; } + }; +private: struct Cursor { int last_fit_x; int line, column; ///< cursor @@ -115,70 +189,6 @@ class TextEdit : public Control { Size2 size; } cache; - struct ColorRegion { - - Color color; - String begin_key; - String end_key; - bool line_only; - bool eq; - ColorRegion(const String &p_begin_key = "", const String &p_end_key = "", const Color &p_color = Color(), bool p_line_only = false) { - begin_key = p_begin_key; - end_key = p_end_key; - color = p_color; - line_only = p_line_only || p_end_key == ""; - eq = begin_key == end_key; - } - }; - - class Text { - public: - struct ColorRegionInfo { - - int region; - bool end; - }; - - struct Line { - int width_cache : 24; - bool marked : 1; - bool breakpoint : 1; - bool hidden : 1; - Map<int, ColorRegionInfo> region_info; - String data; - }; - - private: - const Vector<ColorRegion> *color_regions; - mutable Vector<Line> text; - Ref<Font> font; - int indent_size; - - void _update_line_cache(int p_line) const; - - public: - void set_indent_size(int p_indent_size); - void set_font(const Ref<Font> &p_font); - void set_color_regions(const Vector<ColorRegion> *p_regions) { color_regions = p_regions; } - int get_line_width(int p_line) const; - int get_max_width(bool p_exclude_hidden = false) const; - const Map<int, ColorRegionInfo> &get_color_region_info(int p_line) const; - void set(int p_line, const String &p_text); - void set_marked(int p_line, bool p_marked) { text[p_line].marked = p_marked; } - bool is_marked(int p_line) const { return text[p_line].marked; } - void set_breakpoint(int p_line, bool p_breakpoint) { text[p_line].breakpoint = p_breakpoint; } - bool is_breakpoint(int p_line) const { return text[p_line].breakpoint; } - void set_hidden(int p_line, bool p_hidden) { text[p_line].hidden = p_hidden; } - bool is_hidden(int p_line) const { return text[p_line].hidden; } - void insert(int p_at, const String &p_text); - void remove(int p_at); - int size() const { return text.size(); } - void clear(); - void clear_caches(); - _FORCE_INLINE_ const String &operator[](int p_line) const { return text[p_line].data; } - Text() { indent_size = 4; } - }; - struct TextOperation { enum Type { @@ -209,9 +219,12 @@ class TextEdit : public Control { void _do_text_op(const TextOperation &p_op, bool p_reverse); //syntax coloring + SyntaxHighlighter *syntax_highlighter; HashMap<String, Color> keywords; HashMap<String, Color> member_keywords; + Map<int, HighlighterInfo> _get_line_syntax_highlighting(int p_line); + Vector<ColorRegion> color_regions; Set<String> completion_prefixes; @@ -391,6 +404,13 @@ protected: static void _bind_methods(); public: + SyntaxHighlighter *_get_syntax_highlighting(); + void _set_syntax_highlighting(SyntaxHighlighter *p_syntax_highlighter); + + int _get_line_ending_color_region(int p_line) const; + ColorRegion _get_color_region(int p_region) const; + Map<int, Text::ColorRegionInfo> _get_line_color_region_info(int p_line) const; + enum MenuItems { MENU_CUT, MENU_COPY, @@ -545,10 +565,15 @@ public: bool is_insert_mode() const; void add_keyword_color(const String &p_keyword, const Color &p_color); + bool has_keyword_color(String p_keyword) const; + Color get_keyword_color(String p_keyword) const; + void add_color_region(const String &p_begin_key = String(), const String &p_end_key = String(), const Color &p_color = Color(), bool p_line_only = false); void clear_colors(); void add_member_keyword(const String &p_keyword, const Color &p_color); + bool has_member_color(String p_member) const; + Color get_member_color(String p_member) const; void clear_member_keywords(); int get_v_scroll() const; @@ -621,4 +646,19 @@ public: VARIANT_ENUM_CAST(TextEdit::MenuItems); VARIANT_ENUM_CAST(TextEdit::SearchFlags); +class SyntaxHighlighter { +protected: + TextEdit *text_editor; + +public: + virtual void _update_cache() = 0; + virtual Map<int, TextEdit::HighlighterInfo> _get_line_syntax_highlighting(int p_line) = 0; + + virtual String get_name() = 0; + virtual List<String> get_supported_languages() = 0; + + void set_text_editor(TextEdit *p_text_editor); + TextEdit *get_text_editor(); +}; + #endif // TEXT_EDIT_H diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp index 01b00c34ea..82d983184b 100644 --- a/scene/gui/texture_progress.cpp +++ b/scene/gui/texture_progress.cpp @@ -106,6 +106,33 @@ Ref<Texture> TextureProgress::get_progress_texture() const { return progress; } +void TextureProgress::set_tint_under(const Color &p_tint) { + tint_under = p_tint; + update(); +} + +Color TextureProgress::get_tint_under() const { + return tint_under; +} + +void TextureProgress::set_tint_progress(const Color &p_tint) { + tint_progress = p_tint; + update(); +} + +Color TextureProgress::get_tint_progress() const { + return tint_progress; +} + +void TextureProgress::set_tint_over(const Color &p_tint) { + tint_over = p_tint; + update(); +} + +Color TextureProgress::get_tint_over() const { + return tint_over; +} + Point2 TextureProgress::unit_val_to_uv(float val) { if (progress.is_null()) return Point2(); @@ -117,22 +144,45 @@ Point2 TextureProgress::unit_val_to_uv(float val) { Point2 p = get_relative_center(); - if (val < 0.125) - return Point2(p.x + (1 - p.x) * val * 8, 0); - if (val < 0.25) - return Point2(1, p.y * (val - 0.125) * 8); - if (val < 0.375) - return Point2(1, p.y + (1 - p.y) * (val - 0.25) * 8); - if (val < 0.5) - return Point2(1 - (1 - p.x) * (val - 0.375) * 8, 1); - if (val < 0.625) - return Point2(p.x * (1 - (val - 0.5) * 8), 1); - if (val < 0.75) - return Point2(0, 1 - ((1 - p.y) * (val - 0.625) * 8)); - if (val < 0.875) - return Point2(0, p.y - p.y * (val - 0.75) * 8); - else - return Point2(p.x * (val - 0.875) * 8, 0); + // Minimal version of Liang-Barsky clipping algorithm + float angle = (val * Math_TAU) - Math_PI * 0.5; + Point2 dir = Vector2(Math::cos(angle), Math::sin(angle)); + float t1 = 1.0; + float cp; + float cq; + float cr; + float edgeLeft = 0.0; + float edgeRight = 1.0; + float edgeBottom = 0.0; + float edgeTop = 1.0; + + for (int edge = 0; edge < 4; edge++) { + if (edge == 0) { + if (dir.x > 0) + continue; + cp = -dir.x; + cq = -(edgeLeft - p.x); + } else if (edge == 1) { + if (dir.x < 0) + continue; + cp = dir.x; + cq = (edgeRight - p.x); + } else if (edge == 2) { + if (dir.y > 0) + continue; + cp = -dir.y; + cq = -(edgeBottom - p.y); + } else if (edge == 3) { + if (dir.y < 0) + continue; + cp = dir.y; + cq = (edgeTop - p.y); + } + cr = cq / cp; + if (cr >= 0 && cr < t1) + t1 = cr; + } + return (p + t1 * dir); } Point2 TextureProgress::get_relative_center() { @@ -147,7 +197,7 @@ Point2 TextureProgress::get_relative_center() { return p; } -void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, FillMode p_mode, double p_ratio) { +void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, FillMode p_mode, double p_ratio, const Color &p_modulate) { Vector2 texture_size = p_texture->get_size(); Vector2 topleft = Vector2(stretch_margin[MARGIN_LEFT], stretch_margin[MARGIN_TOP]); Vector2 bottomright = Vector2(stretch_margin[MARGIN_RIGHT], stretch_margin[MARGIN_BOTTOM]); @@ -158,7 +208,7 @@ void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, F if (p_ratio < 1.0) { // Drawing a partially-filled 9-patch is a little tricky - // texture is divided by 3 sections toward fill direction, - // then middle section is streching while the other two aren't. + // then middle section is stretching while the other two aren't. double width_total = 0.0; double width_texture = 0.0; @@ -217,7 +267,7 @@ void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, F } RID ci = get_canvas_item(); - VS::get_singleton()->canvas_item_add_nine_patch(ci, dst_rect, src_rect, p_texture->get_rid(), topleft, bottomright); + VS::get_singleton()->canvas_item_add_nine_patch(ci, dst_rect, src_rect, p_texture->get_rid(), topleft, bottomright, VS::NINE_PATCH_STRETCH, VS::NINE_PATCH_STRETCH, true, p_modulate); } void TextureProgress::_notification(int p_what) { @@ -228,42 +278,42 @@ void TextureProgress::_notification(int p_what) { if (nine_patch_stretch && (mode == FILL_LEFT_TO_RIGHT || mode == FILL_RIGHT_TO_LEFT || mode == FILL_TOP_TO_BOTTOM || mode == FILL_BOTTOM_TO_TOP)) { if (under.is_valid()) { - draw_nine_patch_stretched(under, FILL_LEFT_TO_RIGHT, 1.0); + draw_nine_patch_stretched(under, FILL_LEFT_TO_RIGHT, 1.0, tint_under); } if (progress.is_valid()) { - draw_nine_patch_stretched(progress, mode, get_as_ratio()); + draw_nine_patch_stretched(progress, mode, get_as_ratio(), tint_progress); } if (over.is_valid()) { - draw_nine_patch_stretched(over, FILL_LEFT_TO_RIGHT, 1.0); + draw_nine_patch_stretched(over, FILL_LEFT_TO_RIGHT, 1.0, tint_over); } } else { if (under.is_valid()) - draw_texture(under, Point2()); + draw_texture(under, Point2(), tint_under); if (progress.is_valid()) { Size2 s = progress->get_size(); switch (mode) { case FILL_LEFT_TO_RIGHT: { Rect2 region = Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)); - draw_texture_rect_region(progress, region, region); + draw_texture_rect_region(progress, region, region, tint_progress); } break; case FILL_RIGHT_TO_LEFT: { Rect2 region = Rect2(Point2(s.x - s.x * get_as_ratio(), 0), Size2(s.x * get_as_ratio(), s.y)); - draw_texture_rect_region(progress, region, region); + draw_texture_rect_region(progress, region, region, tint_progress); } break; case FILL_TOP_TO_BOTTOM: { Rect2 region = Rect2(Point2(), Size2(s.x, s.y * get_as_ratio())); - draw_texture_rect_region(progress, region, region); + draw_texture_rect_region(progress, region, region, tint_progress); } break; case FILL_BOTTOM_TO_TOP: { Rect2 region = Rect2(Point2(0, s.y - s.y * get_as_ratio()), Size2(s.x, s.y * get_as_ratio())); - draw_texture_rect_region(progress, region, region); + draw_texture_rect_region(progress, region, region, tint_progress); } break; case FILL_CLOCKWISE: case FILL_COUNTER_CLOCKWISE: { float val = get_as_ratio() * rad_max_degrees / 360; if (val == 1) { Rect2 region = Rect2(Point2(), s); - draw_texture_rect_region(progress, region, region); + draw_texture_rect_region(progress, region, region, tint_progress); } else if (val != 0) { Array pts; float direction = mode == FILL_CLOCKWISE ? 1 : -1; @@ -288,7 +338,9 @@ void TextureProgress::_notification(int p_what) { uvs.push_back(uv); points.push_back(Point2(uv.x * s.x, uv.y * s.y)); } - draw_polygon(points, Vector<Color>(), uvs, progress); + Vector<Color> colors; + colors.push_back(tint_progress); + draw_polygon(points, colors, uvs, progress); } if (Engine::get_singleton()->is_editor_hint()) { Point2 p = progress->get_size(); @@ -300,11 +352,11 @@ void TextureProgress::_notification(int p_what) { } } break; default: - draw_texture_rect_region(progress, Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y))); + draw_texture_rect_region(progress, Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), tint_progress); } } if (over.is_valid()) - draw_texture(over, Point2()); + draw_texture(over, Point2(), tint_over); } } break; @@ -366,6 +418,15 @@ void TextureProgress::_bind_methods() { ClassDB::bind_method(D_METHOD("set_fill_mode", "mode"), &TextureProgress::set_fill_mode); ClassDB::bind_method(D_METHOD("get_fill_mode"), &TextureProgress::get_fill_mode); + ClassDB::bind_method(D_METHOD("set_tint_under", "tint"), &TextureProgress::set_tint_under); + ClassDB::bind_method(D_METHOD("get_tint_under"), &TextureProgress::get_tint_under); + + ClassDB::bind_method(D_METHOD("set_tint_progress", "tint"), &TextureProgress::set_tint_progress); + ClassDB::bind_method(D_METHOD("get_tint_progress"), &TextureProgress::get_tint_progress); + + ClassDB::bind_method(D_METHOD("set_tint_over", "tint"), &TextureProgress::set_tint_over); + ClassDB::bind_method(D_METHOD("get_tint_over"), &TextureProgress::get_tint_over); + ClassDB::bind_method(D_METHOD("set_radial_initial_angle", "mode"), &TextureProgress::set_radial_initial_angle); ClassDB::bind_method(D_METHOD("get_radial_initial_angle"), &TextureProgress::get_radial_initial_angle); @@ -386,6 +447,10 @@ void TextureProgress::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_over", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_over_texture", "get_over_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_progress", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_progress_texture", "get_progress_texture"); ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "fill_mode", PROPERTY_HINT_ENUM, "Left to Right,Right to Left,Top to Bottom,Bottom to Top,Clockwise,Counter Clockwise"), "set_fill_mode", "get_fill_mode"); + ADD_GROUP("Tint", "tint_"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_under", PROPERTY_HINT_COLOR_NO_ALPHA), "set_tint_under", "get_tint_under"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_over", PROPERTY_HINT_COLOR_NO_ALPHA), "set_tint_over", "get_tint_over"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_progress", PROPERTY_HINT_COLOR_NO_ALPHA), "set_tint_progress", "get_tint_progress"); ADD_GROUP("Radial Fill", "radial_"); ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "radial_initial_angle", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_radial_initial_angle", "get_radial_initial_angle"); ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "radial_fill_degrees", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_fill_degrees", "get_fill_degrees"); @@ -417,4 +482,6 @@ TextureProgress::TextureProgress() { stretch_margin[MARGIN_RIGHT] = 0; stretch_margin[MARGIN_BOTTOM] = 0; stretch_margin[MARGIN_TOP] = 0; + + tint_under = tint_progress = tint_over = Color(1, 1, 1); } diff --git a/scene/gui/texture_progress.h b/scene/gui/texture_progress.h index 77c3980e29..34158b5db5 100644 --- a/scene/gui/texture_progress.h +++ b/scene/gui/texture_progress.h @@ -82,6 +82,15 @@ public: void set_nine_patch_stretch(bool p_stretch); bool get_nine_patch_stretch() const; + void set_tint_under(const Color &p_tint); + Color get_tint_under() const; + + void set_tint_progress(const Color &p_tint); + Color get_tint_progress() const; + + void set_tint_over(const Color &p_tint); + Color get_tint_over() const; + Size2 get_minimum_size() const; TextureProgress(); @@ -93,10 +102,11 @@ private: Point2 rad_center_off; bool nine_patch_stretch; int stretch_margin[4]; + Color tint_under, tint_progress, tint_over; Point2 unit_val_to_uv(float val); Point2 get_relative_center(); - void draw_nine_patch_stretched(const Ref<Texture> &p_texture, FillMode p_mode, double p_ratio); + void draw_nine_patch_stretched(const Ref<Texture> &p_texture, FillMode p_mode, double p_ratio, const Color &p_modulate); }; VARIANT_ENUM_CAST(TextureProgress::FillMode); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index cdbdc9b0d7..e7f63997f2 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -2061,322 +2061,318 @@ void Tree::popup_select(int p_option) { item_edited(popup_edited_item_col, popup_edited_item); } -void Tree::_gui_input(Ref<InputEvent> p_event) { - - Ref<InputEventKey> k = p_event; +void Tree::_go_left() { + if (selected_col == 0) { + if (selected_item->get_children() != NULL && !selected_item->is_collapsed()) { + selected_item->set_collapsed(true); + } else { + if (columns.size() == 1) { // goto parent with one column + TreeItem *parent = selected_item->get_parent(); + if (selected_item != get_root() && parent && parent->is_selectable(selected_col) && !(hide_root && parent == get_root())) { + select_single_item(parent, get_root(), selected_col); + } + } else if (selected_item->get_prev_visible()) { + selected_col = columns.size() - 1; + _go_up(); // go to upper column if possible + } + } + } else { + if (select_mode == SELECT_MULTI) { + selected_col--; + emit_signal("cell_selected"); + } else { - if (k.is_valid()) { + selected_item->select(selected_col - 1); + } + } + update(); + accept_event(); + ensure_cursor_is_visible(); +} - if (!k->is_pressed()) - return; - if (k->get_command() || (k->get_shift() && k->get_unicode() == 0) || k->get_metakey()) - return; - if (!root) +void Tree::_go_right() { + if (selected_col == (columns.size() - 1)) { + if (selected_item->get_children() != NULL && selected_item->is_collapsed()) { + selected_item->set_collapsed(false); + } else if (selected_item->get_next_visible()) { + selected_item->select(0); + _go_down(); return; + } + } else { + if (select_mode == SELECT_MULTI) { + selected_col++; + emit_signal("cell_selected"); + } else { - if (hide_root && !root->get_next_visible()) + selected_item->select(selected_col + 1); + } + } + update(); + ensure_cursor_is_visible(); + accept_event(); +} + +void Tree::_go_up() { + TreeItem *prev = NULL; + if (!selected_item) { + prev = get_last_item(); + selected_col = 0; + } else { + + prev = selected_item->get_prev_visible(); + if (last_keypress != 0) { + //incr search next + int col; + prev = _search_item_text(prev, incr_search, &col, true, true); + if (!prev) { + accept_event(); + return; + } + } + } + + if (select_mode == SELECT_MULTI) { + + if (!prev) return; + selected_item = prev; + emit_signal("cell_selected"); + update(); + } else { - switch (k->get_scancode()) { -#define EXIT_BREAK \ - { \ - if (!cursor_can_exit_tree) accept_event(); \ - break; \ + int col = selected_col < 0 ? 0 : selected_col; + while (prev && !prev->cells[col].selectable) + prev = prev->get_prev_visible(); + if (!prev) + return; // do nothing.. + prev->select(col); } - case KEY_RIGHT: { - bool dobreak = true; - //TreeItem *next = NULL; - if (!selected_item) - break; - if (select_mode == SELECT_ROW) { - EXIT_BREAK; - } - if (selected_col > (columns.size() - 1)) { - EXIT_BREAK; - } - if (k->get_alt()) { - selected_item->set_collapsed(false); - TreeItem *next = selected_item->get_children(); - while (next && next != selected_item->next) { - next->set_collapsed(false); - next = next->get_next_visible(); - } - } else if (selected_col == (columns.size() - 1)) { - if (selected_item->get_children() != NULL && selected_item->is_collapsed()) { - selected_item->set_collapsed(false); - } else { - selected_col = 0; - dobreak = false; // fall through to key_down - } - } else { - if (select_mode == SELECT_MULTI) { - selected_col++; - emit_signal("cell_selected"); - } else { + ensure_cursor_is_visible(); + accept_event(); +} - selected_item->select(selected_col + 1); - } - } - update(); - ensure_cursor_is_visible(); +void Tree::_go_down() { + TreeItem *next = NULL; + if (!selected_item) { + + next = hide_root ? root->get_next_visible() : root; + selected_item = 0; + } else { + + next = selected_item->get_next_visible(); + + if (last_keypress != 0) { + //incr search next + int col; + next = _search_item_text(next, incr_search, &col, true); + if (!next) { accept_event(); - if (dobreak) { - break; - } + return; } - case KEY_DOWN: { + } + } - TreeItem *next = NULL; - if (!selected_item) { + if (select_mode == SELECT_MULTI) { - next = hide_root ? root->get_next_visible() : root; - selected_item = 0; - } else { + if (!next) { + return; + } - next = selected_item->get_next_visible(); + selected_item = next; + emit_signal("cell_selected"); + update(); + } else { - //if (diff < uint64_t(GLOBAL_DEF("gui/incr_search_max_interval_msec",2000))) { - if (last_keypress != 0) { - //incr search next - int col; - next = _search_item_text(next, incr_search, &col, true); - if (!next) { - accept_event(); - return; - } - } - } + int col = selected_col < 0 ? 0 : selected_col; - if (select_mode == SELECT_MULTI) { + while (next && !next->cells[col].selectable) + next = next->get_next_visible(); + if (!next) { + return; // do nothing.. + } + next->select(col); + } - if (!next) - EXIT_BREAK; + ensure_cursor_is_visible(); + accept_event(); +} - selected_item = next; - emit_signal("cell_selected"); - update(); - } else { +void Tree::_gui_input(Ref<InputEvent> p_event) { - int col = selected_col < 0 ? 0 : selected_col; + Ref<InputEventKey> k = p_event; - while (next && !next->cells[col].selectable) - next = next->get_next_visible(); - if (!next) - EXIT_BREAK; // do nothing.. - next->select(col); - } + if (p_event->is_action("ui_right") && p_event->is_pressed()) { - ensure_cursor_is_visible(); - accept_event(); + if (!cursor_can_exit_tree) accept_event(); - } break; - case KEY_LEFT: { - bool dobreak = true; + if (!selected_item || select_mode == SELECT_ROW || selected_col > (columns.size() - 1)) { + return; + } + if (k.is_valid() && k->get_alt()) { + selected_item->set_collapsed(false); + TreeItem *next = selected_item->get_children(); + while (next && next != selected_item->next) { + next->set_collapsed(false); + next = next->get_next_visible(); + } + } else { + _go_right(); + } + } else if (p_event->is_action("ui_left") && p_event->is_pressed()) { - //TreeItem *next = NULL; - if (!selected_item) - break; - if (select_mode == SELECT_ROW) { - EXIT_BREAK; - } - if (selected_col < 0) { - EXIT_BREAK; - } - if (k->get_alt()) { - selected_item->set_collapsed(true); - TreeItem *next = selected_item->get_children(); - while (next && next != selected_item->next) { - next->set_collapsed(true); - next = next->get_next_visible(); - } - } else if (selected_col == 0) { - if (selected_item->get_children() != NULL && !selected_item->is_collapsed()) { - selected_item->set_collapsed(true); - } else { - if (columns.size() == 1) { // goto parent with one column - TreeItem *parent = selected_item->get_parent(); - if (selected_item != get_root() && parent && parent->is_selectable(selected_col) && !(hide_root && parent == get_root())) { - select_single_item(parent, get_root(), selected_col); - } - } else { - selected_col = columns.size() - 1; - dobreak = false; // fall through to key_up - } - } - } else { - if (select_mode == SELECT_MULTI) { - selected_col--; - emit_signal("cell_selected"); - } else { + if (!cursor_can_exit_tree) accept_event(); - selected_item->select(selected_col - 1); - } - } - update(); - accept_event(); - ensure_cursor_is_visible(); + if (!selected_item || select_mode == SELECT_ROW || selected_col < 0) { + return; + } - if (dobreak) { - break; - } + if (k.is_valid() && k->get_alt()) { + selected_item->set_collapsed(true); + TreeItem *next = selected_item->get_children(); + while (next && next != selected_item->next) { + next->set_collapsed(true); + next = next->get_next_visible(); } - case KEY_UP: { + } else { + _go_left(); + } - TreeItem *prev = NULL; - if (!selected_item) { - prev = get_last_item(); - selected_col = 0; - } else { + } else if (p_event->is_action("ui_up") && p_event->is_pressed()) { - prev = selected_item->get_prev_visible(); - if (last_keypress != 0) { - //incr search next - int col; - prev = _search_item_text(prev, incr_search, &col, true, true); - if (!prev) { - accept_event(); - return; - } - } - } + if (!cursor_can_exit_tree) accept_event(); - if (select_mode == SELECT_MULTI) { + _go_up(); - if (!prev) - break; - selected_item = prev; - emit_signal("cell_selected"); - update(); - } else { + } else if (p_event->is_action("ui_down") && p_event->is_pressed()) { - int col = selected_col < 0 ? 0 : selected_col; - while (prev && !prev->cells[col].selectable) - prev = prev->get_prev_visible(); - if (!prev) - break; // do nothing.. - prev->select(col); - } + if (!cursor_can_exit_tree) accept_event(); - ensure_cursor_is_visible(); - accept_event(); + _go_down(); - } break; - case KEY_PAGEDOWN: { + } else if (p_event->is_action("ui_page_down") && p_event->is_pressed()) { - TreeItem *next = NULL; - if (!selected_item) - break; - next = selected_item; + if (!cursor_can_exit_tree) accept_event(); - for (int i = 0; i < 10; i++) { + TreeItem *next = NULL; + if (!selected_item) + return; + next = selected_item; - TreeItem *_n = next->get_next_visible(); - if (_n) { - next = _n; - } else { + for (int i = 0; i < 10; i++) { - break; - } - } - if (next == selected_item) - break; + TreeItem *_n = next->get_next_visible(); + if (_n) { + next = _n; + } else { - if (select_mode == SELECT_MULTI) { + return; + } + } + if (next == selected_item) + return; - selected_item = next; - emit_signal("cell_selected"); - update(); - } else { + if (select_mode == SELECT_MULTI) { - while (next && !next->cells[selected_col].selectable) - next = next->get_next_visible(); - if (!next) - EXIT_BREAK; // do nothing.. - next->select(selected_col); - } + selected_item = next; + emit_signal("cell_selected"); + update(); + } else { - ensure_cursor_is_visible(); - } break; - case KEY_PAGEUP: { + while (next && !next->cells[selected_col].selectable) + next = next->get_next_visible(); + if (!next) { + return; // do nothing.. + } + next->select(selected_col); + } - TreeItem *prev = NULL; - if (!selected_item) - break; - prev = selected_item; + ensure_cursor_is_visible(); + } else if (p_event->is_action("ui_page_up") && p_event->is_pressed()) { - for (int i = 0; i < 10; i++) { + if (!cursor_can_exit_tree) accept_event(); - TreeItem *_n = prev->get_prev_visible(); - if (_n) { - prev = _n; - } else { + TreeItem *prev = NULL; + if (!selected_item) + return; + prev = selected_item; - break; - } - } - if (prev == selected_item) - break; + for (int i = 0; i < 10; i++) { - if (select_mode == SELECT_MULTI) { + TreeItem *_n = prev->get_prev_visible(); + if (_n) { + prev = _n; + } else { - selected_item = prev; - emit_signal("cell_selected"); - update(); - } else { + return; + } + } + if (prev == selected_item) + return; - while (prev && !prev->cells[selected_col].selectable) - prev = prev->get_prev_visible(); - if (!prev) - EXIT_BREAK; // do nothing.. - prev->select(selected_col); - } + if (select_mode == SELECT_MULTI) { - ensure_cursor_is_visible(); + selected_item = prev; + emit_signal("cell_selected"); + update(); + } else { - } break; - case KEY_F2: - case KEY_ENTER: - case KEY_KP_ENTER: { - - if (selected_item) { - //bring up editor if possible - if (!edit_selected()) { - emit_signal("item_activated"); - incr_search.clear(); - } - } - accept_event(); + while (prev && !prev->cells[selected_col].selectable) + prev = prev->get_prev_visible(); + if (!prev) { + return; // do nothing.. + } + prev->select(selected_col); + } + ensure_cursor_is_visible(); + } else if (p_event->is_action("ui_accept") && p_event->is_pressed()) { - } break; - case KEY_SPACE: { - if (select_mode == SELECT_MULTI) { - if (!selected_item) - break; - if (selected_item->is_selected(selected_col)) { - selected_item->deselect(selected_col); - emit_signal("multi_selected", selected_item, selected_col, false); - } else if (selected_item->is_selectable(selected_col)) { - selected_item->select(selected_col); - emit_signal("multi_selected", selected_item, selected_col, true); - } - } - accept_event(); + if (selected_item) { + //bring up editor if possible + if (!edit_selected()) { + emit_signal("item_activated"); + incr_search.clear(); + } + } + accept_event(); + } else if (p_event->is_action("ui_select") && p_event->is_pressed()) { - } break; - default: { + if (select_mode == SELECT_MULTI) { + if (!selected_item) + return; + if (selected_item->is_selected(selected_col)) { + selected_item->deselect(selected_col); + emit_signal("multi_selected", selected_item, selected_col, false); + } else if (selected_item->is_selectable(selected_col)) { + selected_item->select(selected_col); + emit_signal("multi_selected", selected_item, selected_col, true); + } + } + accept_event(); + } + + if (k.is_valid()) { // Incremental search + + if (!k->is_pressed()) + return; + if (k->get_command() || (k->get_shift() && k->get_unicode() == 0) || k->get_metakey()) + return; + if (!root) + return; - if (k->get_unicode() > 0) { + if (hide_root && !root->get_next_visible()) + return; - _do_incr_search(String::chr(k->get_unicode())); - accept_event(); + if (k->get_unicode() > 0) { - return; - } else { - if (k->get_scancode() != KEY_SHIFT) - last_keypress = 0; - } - } break; + _do_incr_search(String::chr(k->get_unicode())); + accept_event(); + + return; + } else { + if (k->get_scancode() != KEY_SHIFT) + last_keypress = 0; } } @@ -3911,6 +3907,8 @@ Tree::Tree() { cache.click_id = -1; cache.click_item = NULL; cache.click_column = 0; + cache.hover_cell = -1; + cache.hover_index = -1; last_keypress = 0; focus_in_id = 0; diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 2a8546a743..5af66c5faa 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -507,6 +507,10 @@ private: ValueEvaluator *evaluator; int _count_selected_items(TreeItem *p_from) const; + void _go_left(); + void _go_right(); + void _go_down(); + void _go_up(); protected: static void _bind_methods(); diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp index 4eee0126d8..88e1847533 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_player.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "video_player.h" +#include "scene/scene_string_names.h" #include "os/os.h" #include "servers/audio_server.h" @@ -159,11 +160,7 @@ void VideoPlayer::_notification(int p_notification) { bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus); - if (stream.is_null()) - return; - if (paused) - return; - if (!playback->is_playing()) + if (stream.is_null() || paused || !playback->is_playing()) return; double audio_time = USEC_TO_SEC(OS::get_singleton()->get_ticks_usec()); @@ -174,7 +171,11 @@ void VideoPlayer::_notification(int p_notification) { if (delta == 0) return; - playback->update(delta); + playback->update(delta); // playback->is_playing() returns false in the last video frame + + if (!playback->is_playing()) { + emit_signal(SceneStringNames::get_singleton()->finished); + } } break; @@ -467,6 +468,8 @@ void VideoPlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_video_texture"), &VideoPlayer::get_video_texture); + ADD_SIGNAL(MethodInfo("finished")); + ADD_PROPERTY(PropertyInfo(Variant::INT, "audio_track", PROPERTY_HINT_RANGE, "0,128,1"), "set_audio_track", "get_audio_track"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "VideoStream"), "set_stream", "get_stream"); //ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/loop"), "set_loop", "has_loop") ; diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 3d58aa65f8..ae21775c55 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -121,7 +121,7 @@ Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_h } if (!has_user_agent) { - headers.push_back("User-Agent: GodotEngine/" + String(VERSION_MKSTRING) + " (" + OS::get_singleton()->get_name() + ")"); + headers.push_back("User-Agent: GodotEngine/" + String(VERSION_FULL_BUILD) + " (" + OS::get_singleton()->get_name() + ")"); } if (!has_accept) { diff --git a/scene/main/node.cpp b/scene/main/node.cpp index ac85dd64af..28b4540573 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2010,7 +2010,7 @@ void Node::set_editable_instance(Node *p_node, bool p_editable) { if (!p_editable) { data.editable_instances.erase(p); // Avoid this flag being needlessly saved; - // also give more visual feedback if editable children is reenabled + // also give more visual feedback if editable children is re-enabled set_display_folded(false); } else { data.editable_instances[p] = true; @@ -2502,7 +2502,10 @@ void Node::replace_by(Node *p_node, bool p_keep_data) { Node *child = get_child(0); remove_child(child); - p_node->add_child(child); + if (!child->is_owned_by_parent()) { + // add the custom children to the p_node + p_node->add_child(child); + } } p_node->set_owner(owner); diff --git a/scene/main/node.h b/scene/main/node.h index 4655071228..341869f7ba 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -104,7 +104,7 @@ private: StringName name; SceneTree *tree; bool inside_tree; - bool ready_notified; //this is a small hack, so if a node is added during _ready() to the tree, it corretly gets the _ready() notification + bool ready_notified; //this is a small hack, so if a node is added during _ready() to the tree, it correctly gets the _ready() notification bool ready_first; #ifdef TOOLS_ENABLED NodePath import_path; //path used when imported, used by scene editors to keep tracking diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 55ae9fe1ec..037331dec1 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -498,14 +498,14 @@ bool SceneTree::idle(float p_time) { Size2 win_size = Size2(OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height); if (win_size != last_screen_size) { + last_screen_size = win_size; + _update_root_rect(); + if (use_font_oversampling) { DynamicFontAtSize::font_oversampling = OS::get_singleton()->get_window_size().width / root->get_visible_rect().size.width; DynamicFont::update_oversampling(); } - last_screen_size = win_size; - _update_root_rect(); - emit_signal("screen_resized"); } @@ -615,6 +615,8 @@ void SceneTree::_notification(int p_notification) { } } break; case NOTIFICATION_OS_MEMORY_WARNING: + case NOTIFICATION_WM_MOUSE_ENTER: + case NOTIFICATION_WM_MOUSE_EXIT: case NOTIFICATION_WM_FOCUS_IN: case NOTIFICATION_WM_FOCUS_OUT: { @@ -1778,7 +1780,7 @@ void SceneTree::_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, cons psc->id = last_send_cache_id++; } - //create base packet, lots of harcode because it must be tight + //create base packet, lots of hardcode because it must be tight int ofs = 0; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 1ff1f4b6d8..45a969eeda 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -181,6 +181,7 @@ public: Viewport::GUI::GUI() { mouse_focus = NULL; + mouse_click_grabber = NULL; mouse_focus_button = -1; key_focus = NULL; mouse_over = NULL; @@ -192,6 +193,7 @@ Viewport::GUI::GUI() { } ///////////////////////////////////// + void Viewport::_update_stretch_transform() { if (size_override_stretch && size_override) { @@ -318,6 +320,11 @@ void Viewport::_notification(int p_what) { first->make_current(); } #endif + + // Enable processing for tooltips, collision debugging, physics object picking, etc. + set_process_internal(true); + set_physics_process_internal(true); + } break; case NOTIFICATION_EXIT_TREE: { @@ -345,15 +352,18 @@ void Viewport::_notification(int p_what) { VS::get_singleton()->viewport_set_active(viewport, false); } break; - case NOTIFICATION_PHYSICS_PROCESS: { + case NOTIFICATION_INTERNAL_PROCESS: { if (gui.tooltip_timer >= 0) { - gui.tooltip_timer -= get_physics_process_delta_time(); + gui.tooltip_timer -= get_process_delta_time(); if (gui.tooltip_timer < 0) { _gui_show_tooltip(); } } + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + if (get_tree()->is_debugging_collisions_hint() && contact_2d_debug.is_valid()) { VisualServer::get_singleton()->canvas_item_clear(contact_2d_debug); @@ -1925,6 +1935,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Ref<InputEventGesture> gesture_event = p_event; if (gesture_event.is_valid()) { + gui.key_event_accepted = false; + _gui_cancel_tooltip(); Size2 pos = gesture_event->get_position(); @@ -2017,6 +2029,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { top->notification(Control::NOTIFICATION_MODAL_CLOSE); top->_modal_stack_remove(); top->hide(); + // Close modal, set input as handled + get_tree()->set_input_as_handled(); + return; } } @@ -2264,7 +2279,7 @@ List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) { else p_control->_modal_set_prev_focus_owner(0); - if (gui.mouse_focus && !p_control->is_a_parent_of(gui.mouse_focus)) { + if (gui.mouse_focus && !p_control->is_a_parent_of(gui.mouse_focus) && !gui.mouse_click_grabber) { Ref<InputEventMouseButton> mb; mb.instance(); mb->set_position(gui.mouse_focus->get_local_mouse_position()); @@ -2286,9 +2301,22 @@ Control *Viewport::_gui_get_focus_owner() { void Viewport::_gui_grab_click_focus(Control *p_control) { + gui.mouse_click_grabber = p_control; + call_deferred("_post_gui_grab_click_focus"); +} + +void Viewport::_post_gui_grab_click_focus() { + + Control *focus_grabber = gui.mouse_click_grabber; + if (!focus_grabber) { + // Redundant grab requests were made + return; + } + gui.mouse_click_grabber = NULL; + if (gui.mouse_focus) { - if (gui.mouse_focus == p_control) + if (gui.mouse_focus == focus_grabber) return; Ref<InputEventMouseButton> mb; mb.instance(); @@ -2299,9 +2327,9 @@ void Viewport::_gui_grab_click_focus(Control *p_control) { mb->set_position(click); mb->set_button_index(gui.mouse_focus_button); mb->set_pressed(false); - gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, mb); + gui.mouse_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); - gui.mouse_focus = p_control; + gui.mouse_focus = focus_grabber; gui.focus_inv_xform = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse(); click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos); mb->set_position(click); @@ -2404,9 +2432,14 @@ Rect2 Viewport::get_attach_to_screen_rect() const { void Viewport::set_physics_object_picking(bool p_enable) { physics_object_picking = p_enable; - set_physics_process(physics_object_picking); - if (!physics_object_picking) + if (!physics_object_picking) { physics_picking_events.clear(); + } +} + +bool Viewport::get_physics_object_picking() { + + return physics_object_picking; } Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const { @@ -2420,11 +2453,6 @@ Vector2 Viewport::get_camera_rect_size() const { return size; } -bool Viewport::get_physics_object_picking() { - - return physics_object_picking; -} - bool Viewport::gui_has_modal_stack() const { return gui.modal_stack.size(); @@ -2634,6 +2662,7 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_show_tooltip"), &Viewport::_gui_show_tooltip); ClassDB::bind_method(D_METHOD("_gui_remove_focus"), &Viewport::_gui_remove_focus); + ClassDB::bind_method(D_METHOD("_post_gui_grab_click_focus"), &Viewport::_post_gui_grab_click_focus); ClassDB::bind_method(D_METHOD("set_shadow_atlas_size", "size"), &Viewport::set_shadow_atlas_size); ClassDB::bind_method(D_METHOD("get_shadow_atlas_size"), &Viewport::get_shadow_atlas_size); @@ -2789,6 +2818,7 @@ Viewport::Viewport() { gui.drag_preview = NULL; gui.drag_attempted = false; gui.canvas_sort_index = 0; + gui.roots_order_dirty = false; msaa = MSAA_DISABLED; hdr = true; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 07bbd3f1fa..94e49033e0 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -248,6 +248,7 @@ private: bool key_event_accepted; Control *mouse_focus; + Control *mouse_click_grabber; int mouse_focus_button; Control *key_focus; Control *mouse_over; @@ -323,6 +324,7 @@ private: bool _gui_control_has_focus(const Control *p_control); void _gui_control_grab_focus(Control *p_control); void _gui_grab_click_focus(Control *p_control); + void _post_gui_grab_click_focus(); void _gui_accept_event(); Control *_gui_get_focus_owner(); diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_mask.cpp index 6932a98c17..29ffefd9d6 100644 --- a/scene/resources/bit_mask.cpp +++ b/scene/resources/bit_mask.cpp @@ -42,7 +42,7 @@ void BitMap::create(const Size2 &p_size) { zeromem(bitmask.ptrw(), bitmask.size()); } -void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_treshold) { +void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshold) { ERR_FAIL_COND(p_image.is_null() || p_image->empty()); Ref<Image> img = p_image->duplicate(); @@ -58,7 +58,7 @@ void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_treshold int bbyte = i / 8; int bbit = i % 8; - if (r[i * 2 + 1] / 255.0 > p_treshold) { + if (r[i * 2 + 1] / 255.0 > p_threshold) { w[bbyte] |= (1 << bbit); } } @@ -513,7 +513,7 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { void BitMap::_bind_methods() { ClassDB::bind_method(D_METHOD("create", "size"), &BitMap::create); - ClassDB::bind_method(D_METHOD("create_from_image_alpha", "image", "treshold"), &BitMap::create_from_image_alpha, DEFVAL(0.1)); + ClassDB::bind_method(D_METHOD("create_from_image_alpha", "image", "threshold"), &BitMap::create_from_image_alpha, DEFVAL(0.1)); ClassDB::bind_method(D_METHOD("set_bit", "position", "bit"), &BitMap::set_bit); ClassDB::bind_method(D_METHOD("get_bit", "position"), &BitMap::get_bit); diff --git a/scene/resources/bit_mask.h b/scene/resources/bit_mask.h index d69db00d51..dcd5edb4fb 100644 --- a/scene/resources/bit_mask.h +++ b/scene/resources/bit_mask.h @@ -54,7 +54,7 @@ protected: public: void create(const Size2 &p_size); - void create_from_image_alpha(const Ref<Image> &p_image, float p_treshold = 0.1); + void create_from_image_alpha(const Ref<Image> &p_image, float p_threshold = 0.1); void set_bit(const Point2 &p_pos, bool p_value); bool get_bit(const Point2 &p_pos) const; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 3e244aa8f8..ea70797530 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -582,6 +582,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_icon("checked", "PopupMenu", make_icon(checked_png)); theme->set_icon("unchecked", "PopupMenu", make_icon(unchecked_png)); + theme->set_icon("radio_checked", "PopupMenu", make_icon(radio_checked_png)); + theme->set_icon("radio_unchecked", "PopupMenu", make_icon(radio_unchecked_png)); theme->set_icon("submenu", "PopupMenu", make_icon(submenu_png)); theme->set_font("font", "PopupMenu", default_font); diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 23c6dc200b..26e29b3ccb 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -80,6 +80,14 @@ void DynamicFontData::set_force_autohinter(bool p_force) { void DynamicFontData::_bind_methods() { ClassDB::bind_method(D_METHOD("set_font_path", "path"), &DynamicFontData::set_font_path); ClassDB::bind_method(D_METHOD("get_font_path"), &DynamicFontData::get_font_path); + ClassDB::bind_method(D_METHOD("set_hinting", "mode"), &DynamicFontData::set_hinting); + ClassDB::bind_method(D_METHOD("get_hinting"), &DynamicFontData::get_hinting); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting"); + + BIND_ENUM_CONSTANT(HINTING_NONE); + BIND_ENUM_CONSTANT(HINTING_LIGHT); + BIND_ENUM_CONSTANT(HINTING_NORMAL); ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_path", PROPERTY_HINT_FILE, "*.ttf,*.otf"), "set_font_path", "get_font_path"); } @@ -87,6 +95,7 @@ void DynamicFontData::_bind_methods() { DynamicFontData::DynamicFontData() { force_autohinter = false; + hinting = DynamicFontData::HINTING_NORMAL; font_mem = NULL; font_mem_size = 0; } @@ -212,8 +221,6 @@ Error DynamicFontAtSize::_load() { if (id.filter) texture_flags |= Texture::FLAG_FILTER; - //print_line("ASCENT: "+itos(ascent)+" descent "+itos(descent)+" hinted: "+itos(face->face_flags&FT_FACE_FLAG_HINTER)); - valid = true; return OK; } @@ -454,15 +461,28 @@ void DynamicFontAtSize::_update_char(CharType p_char) { char_map[p_char] = ch; return; } - int error = FT_Load_Char(face, p_char, FT_HAS_COLOR(face) ? FT_LOAD_COLOR : FT_LOAD_DEFAULT | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)); + + int ft_hinting; + + switch (font->hinting) { + case DynamicFontData::HINTING_NONE: + ft_hinting = FT_LOAD_NO_HINTING; + break; + case DynamicFontData::HINTING_LIGHT: + ft_hinting = FT_LOAD_TARGET_LIGHT; + break; + default: + ft_hinting = FT_LOAD_TARGET_NORMAL; + break; + } + + int error = FT_Load_Char(face, p_char, FT_HAS_COLOR(face) ? FT_LOAD_COLOR : FT_LOAD_DEFAULT | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0) | ft_hinting); if (!error) { error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); } if (error) { int advance = 0; - //stbtt_GetCodepointHMetrics(&font->info, p_char, &advance, 0); - //print_line("char has no bitmap: "+itos(p_char)+" but advance is "+itos(advance*scale)); Character ch; ch.texture_idx = -1; ch.advance = advance; @@ -477,7 +497,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) { int w = slot->bitmap.width; int h = slot->bitmap.rows; - //int p = slot->bitmap.pitch; int yofs = slot->bitmap_top; int xofs = slot->bitmap_left; int advance = slot->advance.x >> 6; @@ -536,8 +555,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) { break; } - //print_line("CHAR: "+String::chr(p_char)+" TEX INDEX: "+itos(tex_index)+" X: "+itos(tex_x)+" Y: "+itos(tex_y)); - if (tex_index == -1) { //could not find texture to fit, create one tex_x = 0; @@ -645,8 +662,6 @@ void DynamicFontAtSize::_update_char(CharType p_char) { chr.rect.position /= oversampling; chr.rect.size /= oversampling; - //print_line("CHAR: "+String::chr(p_char)+" TEX INDEX: "+itos(tex_index)+" RECT: "+chr.rect+" X OFS: "+itos(xofs)+" Y OFS: "+itos(yofs)); - char_map[p_char] = chr; } @@ -758,6 +773,18 @@ void DynamicFont::set_use_filter(bool p_enable) { _reload_cache(); } +DynamicFontData::Hinting DynamicFontData::get_hinting() const { + + return hinting; +} + +void DynamicFontData::set_hinting(Hinting p_hinting) { + + if (hinting == p_hinting) + return; + hinting = p_hinting; +} + int DynamicFont::get_spacing(int p_type) const { if (p_type == SPACING_TOP) { diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index d8adf35b6b..db8bd87587 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -64,10 +64,20 @@ public: } }; + enum Hinting { + HINTING_NONE, + HINTING_LIGHT, + HINTING_NORMAL + }; + + Hinting get_hinting() const; + void set_hinting(Hinting p_hinting); + private: const uint8_t *font_mem; int font_mem_size; bool force_autohinter; + Hinting hinting; String font_path; Map<CacheID, DynamicFontAtSize *> size_cache; @@ -91,6 +101,8 @@ public: ~DynamicFontData(); }; +VARIANT_ENUM_CAST(DynamicFontData::Hinting); + class DynamicFontAtSize : public Reference { GDCLASS(DynamicFontAtSize, Reference) diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index ceac65ffa7..a83ef198fb 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -1482,9 +1482,9 @@ bool SpatialMaterial::is_grow_enabled() const { return grow_enabled; } -void SpatialMaterial::set_alpha_scissor_threshold(float p_treshold) { - alpha_scissor_threshold = p_treshold; - VS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_scissor_threshold, p_treshold); +void SpatialMaterial::set_alpha_scissor_threshold(float p_threshold) { + alpha_scissor_threshold = p_threshold; + VS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_scissor_threshold, p_threshold); } float SpatialMaterial::get_alpha_scissor_threshold() const { diff --git a/scene/resources/material.h b/scene/resources/material.h index 10bbcfd642..2c297cda41 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -566,7 +566,7 @@ public: void set_grow(float p_grow); float get_grow() const; - void set_alpha_scissor_threshold(float p_treshold); + void set_alpha_scissor_threshold(float p_threshold); float get_alpha_scissor_threshold() const; void set_on_top_of_alpha(); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 949ba12a4c..b832ea1239 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -315,6 +315,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { } } + ERR_FAIL_COND_V(arrays.size() != ARRAY_MAX, Ref<ArrayMesh>()); + { PoolVector<int>::Write ir; PoolVector<int> indices = arrays[ARRAY_INDEX]; diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 1eaa007bd7..94a7a055a3 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -189,7 +189,7 @@ public: }; /** - Similar to quadmesh but with tesselation support + Similar to quadmesh but with tessellation support */ class PlaneMesh : public PrimitiveMesh { diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp index 91c801c016..030b822f3b 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/scene_format_text.cpp @@ -1445,8 +1445,15 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, static String _valprop(const String &p_name) { - if (p_name.find("\"") != -1 || p_name.find("=") != -1 || p_name.find(" ") != -1) - return "\"" + p_name.c_escape_multiline() + "\""; + // Escape and quote strings with extended ASCII or further Unicode characters + // as well as '"', '=' or ' ' (32) + const CharType *cstr = p_name.c_str(); + for (int i = 0; cstr[i]; i++) { + if (cstr[i] == '=' || cstr[i] == '"' || cstr[i] < 33 || cstr[i] > 126) { + return "\"" + p_name.c_escape_multiline() + "\""; + } + } + // Keep as is return p_name; } @@ -1506,7 +1513,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r title += "load_steps=" + itos(load_steps) + " "; } title += "format=" + itos(FORMAT_VERSION) + ""; - //title+="engine_version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\""; f->store_string(title); f->store_line("]\n"); //one empty line diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h index ed655b8a93..7eb0406bd8 100644 --- a/scene/resources/shape_2d.h +++ b/scene/resources/shape_2d.h @@ -45,7 +45,7 @@ protected: Shape2D(const RID &p_rid); public: - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return true; } + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return get_rect().has_point(p_point); } void set_custom_solver_bias(real_t p_bias); real_t get_custom_solver_bias() const; diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index de75bb3976..626fda50df 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -101,7 +101,7 @@ StyleBox::StyleBox() { } } -void StyleBoxTexture::set_texture(RES p_texture) { +void StyleBoxTexture::set_texture(Ref<Texture> p_texture) { if (texture == p_texture) return; @@ -112,12 +112,12 @@ void StyleBoxTexture::set_texture(RES p_texture) { _change_notify("texture"); } -RES StyleBoxTexture::get_texture() const { +Ref<Texture> StyleBoxTexture::get_texture() const { return texture; } -void StyleBoxTexture::set_normal_map(RES p_normal_map) { +void StyleBoxTexture::set_normal_map(Ref<Texture> p_normal_map) { if (normal_map == p_normal_map) return; @@ -125,7 +125,7 @@ void StyleBoxTexture::set_normal_map(RES p_normal_map) { emit_changed(); } -RES StyleBoxTexture::get_normal_map() const { +Ref<Texture> StyleBoxTexture::get_normal_map() const { return normal_map; } @@ -650,14 +650,14 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { style_rect = style_rect.grow(-((aa_size + 1) / 2)); } - //adapt borders (prevent weired overlapping/glitchy drawings) + //adapt borders (prevent weird overlapping/glitchy drawings) int width = MAX(style_rect.size.width, 0); int height = MAX(style_rect.size.height, 0); int adapted_border[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX }; adapt_values(MARGIN_TOP, MARGIN_BOTTOM, adapted_border, border_width, height, height, height); adapt_values(MARGIN_LEFT, MARGIN_RIGHT, adapted_border, border_width, width, width, width); - //adapt corners (prevent weired overlapping/glitchy drawings) + //adapt corners (prevent weird overlapping/glitchy drawings) int adapted_corner[4] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX }; adapt_values(CORNER_TOP_RIGHT, CORNER_BOTTOM_RIGHT, adapted_corner, corner_radius, height, height - adapted_border[MARGIN_BOTTOM], height - adapted_border[MARGIN_TOP]); adapt_values(CORNER_TOP_LEFT, CORNER_BOTTOM_LEFT, adapted_corner, corner_radius, height, height - adapted_border[MARGIN_BOTTOM], height - adapted_border[MARGIN_TOP]); diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index fb79aa360e..c1d84fe19f 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -112,11 +112,11 @@ public: void set_region_rect(const Rect2 &p_region_rect); Rect2 get_region_rect() const; - void set_texture(RES p_texture); - RES get_texture() const; + void set_texture(Ref<Texture> p_texture); + Ref<Texture> get_texture() const; - void set_normal_map(RES p_normal_map); - RES get_normal_map() const; + void set_normal_map(Ref<Texture> p_normal_map); + Ref<Texture> get_normal_map() const; void set_draw_center(bool p_enabled); bool is_draw_center_enabled() const; diff --git a/servers/arvr_server.cpp b/servers/arvr_server.cpp index 8620b182df..f9d402fe7b 100644 --- a/servers/arvr_server.cpp +++ b/servers/arvr_server.cpp @@ -44,6 +44,7 @@ void ARVRServer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_world_scale"), &ARVRServer::set_world_scale); ClassDB::bind_method(D_METHOD("get_reference_frame"), &ARVRServer::get_reference_frame); ClassDB::bind_method(D_METHOD("center_on_hmd", "rotation_mode", "keep_height"), &ARVRServer::center_on_hmd); + ClassDB::bind_method(D_METHOD("get_hmd_transform"), &ARVRServer::get_hmd_transform); ADD_PROPERTY(PropertyInfo(Variant::REAL, "world_scale"), "set_world_scale", "get_world_scale"); @@ -54,8 +55,13 @@ void ARVRServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tracker_count"), &ARVRServer::get_tracker_count); ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &ARVRServer::get_tracker); + ClassDB::bind_method(D_METHOD("get_primary_interface"), &ARVRServer::get_primary_interface); ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &ARVRServer::set_primary_interface); + ClassDB::bind_method(D_METHOD("get_last_process_usec"), &ARVRServer::get_last_process_usec); + ClassDB::bind_method(D_METHOD("get_last_commit_usec"), &ARVRServer::get_last_commit_usec); + ClassDB::bind_method(D_METHOD("get_last_frame_usec"), &ARVRServer::get_last_frame_usec); + BIND_ENUM_CONSTANT(TRACKER_CONTROLLER); BIND_ENUM_CONSTANT(TRACKER_BASESTATION); BIND_ENUM_CONSTANT(TRACKER_ANCHOR); @@ -132,6 +138,14 @@ void ARVRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) }; }; +Transform ARVRServer::get_hmd_transform() { + Transform hmd_transform; + if (primary_interface != NULL) { + hmd_transform = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, hmd_transform); + }; + return hmd_transform; +}; + void ARVRServer::add_interface(const Ref<ARVRInterface> &p_interface) { ERR_FAIL_COND(p_interface.is_null()); @@ -314,6 +328,42 @@ void ARVRServer::clear_primary_interface_if(const Ref<ARVRInterface> &p_primary_ }; }; +uint64_t ARVRServer::get_last_process_usec() { + return last_process_usec; +}; + +uint64_t ARVRServer::get_last_commit_usec() { + return last_commit_usec; +}; + +uint64_t ARVRServer::get_last_frame_usec() { + return last_frame_usec; +}; + +void ARVRServer::_process() { + /* called from visual_server_viewport.draw_viewports right before we start drawing our viewports */ + + /* mark for our frame timing */ + last_process_usec = OS::get_singleton()->get_ticks_usec(); + + /* process all active interfaces */ + for (int i = 0; i < interfaces.size(); i++) { + if (!interfaces[i].is_valid()) { + // ignore, not a valid reference + } else if (interfaces[i]->is_initialized()) { + interfaces[i]->process(); + }; + }; +}; + +void ARVRServer::_mark_commit() { + /* time this */ + last_commit_usec = OS::get_singleton()->get_ticks_usec(); + + /* now store our difference as we may overwrite last_process_usec before this is accessed */ + last_frame_usec = last_commit_usec - last_process_usec; +}; + ARVRServer::ARVRServer() { singleton = this; world_scale = 1.0; diff --git a/servers/arvr_server.h b/servers/arvr_server.h index 34f143c0e0..1f4d84fe19 100644 --- a/servers/arvr_server.h +++ b/servers/arvr_server.h @@ -31,6 +31,7 @@ #ifndef ARVR_SERVER_H #define ARVR_SERVER_H +#include "os/os.h" #include "os/thread_safe.h" #include "reference.h" #include "rid.h" @@ -49,7 +50,7 @@ class ARVRPositionalTracker; Also each positioning tracker is accessible from here. I've added some additional info into this header file that should move - into the documention, I will do so when we're close to accepting this PR + into the documentation, I will do so when we're close to accepting this PR or as a separate PR once this has been merged into the master branch. **/ @@ -84,6 +85,10 @@ private: Transform world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */ Transform reference_frame; /* our reference frame */ + uint64_t last_process_usec; /* for frame timing, usec when we did our processing */ + uint64_t last_commit_usec; /* for frame timing, usec when we finished committing both eyes */ + uint64_t last_frame_usec; /* time it took between process and commiting, we should probably average this over the last x frames */ + protected: static ARVRServer *singleton; @@ -134,6 +139,11 @@ public: void center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height); /* + get_hmd_transform gets our hmd transform (centered between eyes) with most up to date tracking, relative to the origin + */ + Transform get_hmd_transform(); + + /* Interfaces are objects that 'glue' Godot to an AR or VR SDK such as the Oculus SDK, OpenVR, OpenHMD, etc. */ void add_interface(const Ref<ARVRInterface> &p_interface); @@ -163,6 +173,13 @@ public: ARVRPositionalTracker *get_tracker(int p_index) const; ARVRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const; + uint64_t get_last_process_usec(); + uint64_t get_last_commit_usec(); + uint64_t get_last_frame_usec(); + + void _process(); + void _mark_commit(); + ARVRServer(); ~ARVRServer(); }; diff --git a/servers/audio/effects/audio_effect_compressor.cpp b/servers/audio/effects/audio_effect_compressor.cpp index 0252b2f341..8c70b51f8d 100644 --- a/servers/audio/effects/audio_effect_compressor.cpp +++ b/servers/audio/effects/audio_effect_compressor.cpp @@ -236,7 +236,7 @@ void AudioEffectCompressor::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "attack_us", PROPERTY_HINT_RANGE, "20,2000,1"), "set_attack_us", "get_attack_us"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "release_ms", PROPERTY_HINT_RANGE, "20,2000,1"), "set_release_ms", "get_release_ms"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "mix", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_mix", "get_mix"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sidechain", PROPERTY_HINT_ENUM), "set_sidechain", "get_sidechain"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "sidechain", PROPERTY_HINT_ENUM), "set_sidechain", "get_sidechain"); } AudioEffectCompressor::AudioEffectCompressor() { diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 5c453a3113..b08e41301a 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -101,6 +101,18 @@ int AudioDriver::get_total_channels_by_speaker_mode(AudioDriver::SpeakerMode p_m ERR_FAIL_V(2); } +Array AudioDriver::get_device_list() { + Array list; + + list.push_back("Default"); + + return list; +} + +String AudioDriver::get_device() { + return "Default"; +} + AudioDriver::AudioDriver() { _last_mix_time = 0; @@ -153,7 +165,7 @@ void AudioDriverManager::initialize(int p_driver) { ERR_PRINT("AudioDriverManager: all drivers failed, falling back to dummy driver"); dummy_driver.set_singleton(); } else { - ERR_PRINT("AudioDriverManager: dummy driver faild to init()"); + ERR_PRINT("AudioDriverManager: dummy driver failed to init()"); } } @@ -172,6 +184,12 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { int todo = p_frames; + if (channel_count != get_channel_count()) { + // Amount of channels changed due to a device change + // reinitialize the buses channels and buffers + init_channels_and_buffers(); + } + while (todo) { if (to_mix == 0) { @@ -485,8 +503,8 @@ void AudioServer::set_bus_count(int p_count) { } buses[i] = memnew(Bus); - buses[i]->channels.resize(get_channel_count()); - for (int j = 0; j < get_channel_count(); j++) { + buses[i]->channels.resize(channel_count); + for (int j = 0; j < channel_count; j++) { buses[i]->channels[j].buffer.resize(buffer_size); } buses[i]->name = attempt; @@ -518,6 +536,8 @@ void AudioServer::remove_bus(int p_index) { memdelete(buses[p_index]); buses.remove(p_index); unlock(); + + emit_signal("bus_layout_changed"); } void AudioServer::add_bus(int p_at_pos) { @@ -555,8 +575,8 @@ void AudioServer::add_bus(int p_at_pos) { } Bus *bus = memnew(Bus); - bus->channels.resize(get_channel_count()); - for (int j = 0; j < get_channel_count(); j++) { + bus->channels.resize(channel_count); + for (int j = 0; j < channel_count; j++) { bus->channels[j].buffer.resize(buffer_size); } bus->name = attempt; @@ -571,6 +591,8 @@ void AudioServer::add_bus(int p_at_pos) { buses.push_back(bus); else buses.insert(p_at_pos, bus); + + emit_signal("bus_layout_changed"); } void AudioServer::move_bus(int p_bus, int p_to_pos) { @@ -593,6 +615,8 @@ void AudioServer::move_bus(int p_bus, int p_to_pos) { } else { buses.insert(p_to_pos - 1, bus); } + + emit_signal("bus_layout_changed"); } int AudioServer::get_bus_count() const { @@ -854,17 +878,29 @@ bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const { return buses[p_bus]->channels[p_channel].active; } +void AudioServer::init_channels_and_buffers() { + channel_count = get_channel_count(); + temp_buffer.resize(channel_count); + + for (int i = 0; i < temp_buffer.size(); i++) { + temp_buffer[i].resize(buffer_size); + } + + for (int i = 0; i < buses.size(); i++) { + buses[i]->channels.resize(channel_count); + for (int j = 0; j < channel_count; j++) { + buses[i]->channels[j].buffer.resize(buffer_size); + } + } +} + void AudioServer::init() { channel_disable_threshold_db = GLOBAL_DEF("audio/channel_disable_threshold_db", -60.0); channel_disable_frames = float(GLOBAL_DEF("audio/channel_disable_time", 2.0)) * get_mix_rate(); - buffer_size = 1024; //harcoded for now - - temp_buffer.resize(get_channel_count()); + buffer_size = 1024; //hardcoded for now - for (int i = 0; i < temp_buffer.size(); i++) { - temp_buffer[i].resize(buffer_size); - } + init_channels_and_buffers(); mix_count = 0; set_bus_count(1); @@ -1046,8 +1082,8 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) { bus_map[bus->name] = bus; buses[i] = bus; - buses[i]->channels.resize(get_channel_count()); - for (int j = 0; j < get_channel_count(); j++) { + buses[i]->channels.resize(channel_count); + for (int j = 0; j < channel_count; j++) { buses[i]->channels[j].buffer.resize(buffer_size); } _update_bus_effects(i); @@ -1084,6 +1120,21 @@ Ref<AudioBusLayout> AudioServer::generate_bus_layout() const { return state; } +Array AudioServer::get_device_list() { + + return AudioDriver::get_singleton()->get_device_list(); +} + +String AudioServer::get_device() { + + return AudioDriver::get_singleton()->get_device(); +} + +void AudioServer::set_device(String device) { + + AudioDriver::get_singleton()->set_device(device); +} + void AudioServer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bus_count", "amount"), &AudioServer::set_bus_count); @@ -1130,6 +1181,9 @@ void AudioServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_speaker_mode"), &AudioServer::get_speaker_mode); ClassDB::bind_method(D_METHOD("get_mix_rate"), &AudioServer::get_mix_rate); + ClassDB::bind_method(D_METHOD("get_device_list"), &AudioServer::get_device_list); + ClassDB::bind_method(D_METHOD("get_device"), &AudioServer::get_device); + ClassDB::bind_method(D_METHOD("set_device"), &AudioServer::set_device); ClassDB::bind_method(D_METHOD("set_bus_layout", "bus_layout"), &AudioServer::set_bus_layout); ClassDB::bind_method(D_METHOD("generate_bus_layout"), &AudioServer::generate_bus_layout); @@ -1148,6 +1202,7 @@ AudioServer::AudioServer() { audio_data_max_mem = 0; audio_data_lock = Mutex::create(); mix_frames = 0; + channel_count = 0; to_mix = 0; } diff --git a/servers/audio_server.h b/servers/audio_server.h index 188d38db94..af2668b69e 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -70,6 +70,9 @@ public: virtual void start() = 0; virtual int get_mix_rate() const = 0; virtual SpeakerMode get_speaker_mode() const = 0; + virtual Array get_device_list(); + virtual String get_device(); + virtual void set_device(String device) {} virtual void lock() = 0; virtual void unlock() = 0; virtual void finish() = 0; @@ -130,6 +133,7 @@ private: float channel_disable_threshold_db; uint32_t channel_disable_frames; + int channel_count; int to_mix; struct Bus { @@ -186,6 +190,8 @@ private: Mutex *audio_data_lock; + void init_channels_and_buffers(); + void _mix_step(); struct CallbackItem { @@ -297,6 +303,10 @@ public: void set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout); Ref<AudioBusLayout> generate_bus_layout() const; + Array get_device_list(); + String get_device(); + void set_device(String device); + AudioServer(); virtual ~AudioServer(); }; diff --git a/servers/physics/shape_sw.h b/servers/physics/shape_sw.h index 7f7f9f4f98..7be818b23c 100644 --- a/servers/physics/shape_sw.h +++ b/servers/physics/shape_sw.h @@ -240,7 +240,7 @@ public: _FORCE_INLINE_ real_t get_height() const { return height; } _FORCE_INLINE_ real_t get_radius() const { return radius; } - virtual real_t get_area() { return 4.0 / 3.0 * Math_PI * radius * radius * radius + height * Math_PI * radius * radius; } + virtual real_t get_area() const { return 4.0 / 3.0 * Math_PI * radius * radius * radius + height * Math_PI * radius * radius; } virtual PhysicsServer::ShapeType get_type() const { return PhysicsServer::SHAPE_CAPSULE; } diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp index 7fba8acebd..d49c1b8376 100644 --- a/servers/physics_2d/joints_2d_sw.cpp +++ b/servers/physics_2d/joints_2d_sw.cpp @@ -146,14 +146,19 @@ bool PinJoint2DSW::setup(real_t p_step) { return true; } +inline Vector2 custom_cross(const Vector2 &p_vec, real_t p_other) { + + return Vector2(p_other * p_vec.y, -p_other * p_vec.x); +} + void PinJoint2DSW::solve(real_t p_step) { // compute relative velocity - Vector2 vA = A->get_linear_velocity() - rA.cross(A->get_angular_velocity()); + Vector2 vA = A->get_linear_velocity() - custom_cross(rA, A->get_angular_velocity()); Vector2 rel_vel; if (B) - rel_vel = B->get_linear_velocity() - rB.cross(B->get_angular_velocity()) - vA; + rel_vel = B->get_linear_velocity() - custom_cross(rB, B->get_angular_velocity()) - vA; else rel_vel = -vA; diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index db5e14043c..f01a4c2f64 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -96,7 +96,7 @@ void PhysicsDirectBodyState::_bind_methods() { ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &PhysicsDirectBodyState::add_force); ClassDB::bind_method(D_METHOD("add_torque", "torque"), &PhysicsDirectBodyState::add_torque); ClassDB::bind_method(D_METHOD("apply_impulse", "position", "j"), &PhysicsDirectBodyState::apply_impulse); - ClassDB::bind_method(D_METHOD("apply_torqe_impulse", "j"), &PhysicsDirectBodyState::apply_torque_impulse); + ClassDB::bind_method(D_METHOD("apply_torque_impulse", "j"), &PhysicsDirectBodyState::apply_torque_impulse); ClassDB::bind_method(D_METHOD("set_sleep_state", "enabled"), &PhysicsDirectBodyState::set_sleep_state); ClassDB::bind_method(D_METHOD("is_sleeping"), &PhysicsDirectBodyState::is_sleeping); diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index aaac32a4f2..1bad7e652b 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -80,6 +80,7 @@ static void _debugger_get_resource_usage(List<ScriptDebuggerRemote::ResourceUsag ShaderTypes *shader_types = NULL; PhysicsServer *_createGodotPhysicsCallback() { + WARN_PRINT("The GodotPhysics 3D physics engine is deprecated and will be removed in Godot 3.2. You should use the Bullet physics engine instead (configurable in your project settings)."); return memnew(PhysicsServerSW); } @@ -163,8 +164,8 @@ void register_server_types() { GLOBAL_DEF(PhysicsServerManager::setting_property_name, "DEFAULT"); ProjectSettings::get_singleton()->set_custom_property_info(PhysicsServerManager::setting_property_name, PropertyInfo(Variant::STRING, PhysicsServerManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT")); - PhysicsServerManager::register_server("GodotPhysics", &_createGodotPhysicsCallback); - PhysicsServerManager::set_default_server("GodotPhysics"); + PhysicsServerManager::register_server("GodotPhysics - deprecated", &_createGodotPhysicsCallback); + PhysicsServerManager::set_default_server("GodotPhysics - deprecated"); } void unregister_server_types() { diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 378a05cdfe..8bf112b0de 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -749,7 +749,6 @@ public: struct CommandMesh : public Command { RID mesh; - RID skeleton; RID texture; RID normal_map; CommandMesh() { type = TYPE_MESH; } @@ -758,7 +757,6 @@ public: struct CommandMultiMesh : public Command { RID multimesh; - RID skeleton; RID texture; RID normal_map; CommandMultiMesh() { type = TYPE_MULTIMESH; } @@ -924,7 +922,7 @@ public: case Item::Command::TYPE_MESH: { const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c); - AABB aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, mesh->skeleton); + AABB aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, RID()); r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); @@ -1016,7 +1014,7 @@ public: virtual void canvas_begin() = 0; virtual void canvas_end() = 0; - virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light) = 0; + virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) = 0; virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0; struct LightOccluderInstance : public RID_Data { diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index d9f2c949e9..37aeef8999 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -124,6 +124,9 @@ const char *ShaderLanguage::token_names[TK_MAX] = { "TYPE_ISAMPLER2D", "TYPE_USAMPLER2D", "TYPE_SAMPLERCUBE", + "INTERPOLATION_FLAT", + "INTERPOLATION_NO_PERSPECTIVE", + "INTERPOLATION_SMOOTH", "PRECISION_LOW", "PRECISION_MID", "PRECISION_HIGH", @@ -1489,11 +1492,6 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "abs", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID } }, { "abs", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID } }, - { "abs", TYPE_UINT, { TYPE_UINT, TYPE_VOID } }, - { "abs", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID } }, - { "abs", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID } }, - { "abs", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID } }, - { "sign", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, { "sign", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, { "sign", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, @@ -1608,7 +1606,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BOOL, TYPE_VOID } }, - { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BVEC3, TYPE_VOID } }, + { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BVEC4, TYPE_VOID } }, { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, { "step", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, @@ -1641,10 +1639,10 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "floatBitsToInt", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID } }, { "floatBitsToInt", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID } }, - { "floatBitsToUInt", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID } }, - { "floatBitsToUInt", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID } }, - { "floatBitsToUInt", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID } }, - { "floatBitsToUInt", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID } }, + { "floatBitsToUint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID } }, + { "floatBitsToUint", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID } }, + { "floatBitsToUint", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID } }, + { "floatBitsToUint", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID } }, { "intBitsToFloat", TYPE_FLOAT, { TYPE_INT, TYPE_VOID } }, { "intBitsToFloat", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID } }, @@ -3699,26 +3697,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct //todo parse default value tk = _get_token(); - if (tk.type == TK_OP_ASSIGN) { - - Node *expr = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>()); - if (!expr) - return ERR_PARSE_ERROR; - if (expr->type != Node::TYPE_CONSTANT) { - _set_error("Expected constant expression after '='"); - return ERR_PARSE_ERROR; - } - - ConstantNode *cn = static_cast<ConstantNode *>(expr); - - uniform.default_value.resize(cn->values.size()); - - if (!convert_constant(cn, uniform.type, uniform.default_value.ptrw())) { - _set_error("Can't convert constant to " + get_datatype_name(uniform.type)); - return ERR_PARSE_ERROR; - } - tk = _get_token(); - } if (tk.type == TK_COLON) { //hint @@ -3834,6 +3812,27 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); } + if (tk.type == TK_OP_ASSIGN) { + + Node *expr = _parse_and_reduce_expression(NULL, Map<StringName, BuiltInInfo>()); + if (!expr) + return ERR_PARSE_ERROR; + if (expr->type != Node::TYPE_CONSTANT) { + _set_error("Expected constant expression after '='"); + return ERR_PARSE_ERROR; + } + + ConstantNode *cn = static_cast<ConstantNode *>(expr); + + uniform.default_value.resize(cn->values.size()); + + if (!convert_constant(cn, uniform.type, uniform.default_value.ptrw())) { + _set_error("Can't convert constant to " + get_datatype_name(uniform.type)); + return ERR_PARSE_ERROR; + } + tk = _get_token(); + } + shader->uniforms[name] = uniform; if (tk.type != TK_SEMICOLON) { diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index 330b2bd0d2..dd8d07f00d 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -46,7 +46,7 @@ void VisualServerCanvas::_render_canvas_item_tree(Item *p_canvas_item, const Tra for (int i = 0; i < z_range; i++) { if (!z_list[i]) continue; - VSG::canvas_render->canvas_render_items(z_list[i], VS::CANVAS_ITEM_Z_MIN + i, p_modulate, p_lights); + VSG::canvas_render->canvas_render_items(z_list[i], VS::CANVAS_ITEM_Z_MIN + i, p_modulate, p_lights, p_transform); } } @@ -214,7 +214,7 @@ void VisualServerCanvas::render_canvas(Canvas *p_canvas, const Transform2D &p_tr _light_mask_canvas_items(VS::CANVAS_ITEM_Z_MIN + i, z_list[i], p_masked_lights); } - VSG::canvas_render->canvas_render_items(z_list[i], VS::CANVAS_ITEM_Z_MIN + i, p_canvas->modulate, p_lights); + VSG::canvas_render->canvas_render_items(z_list[i], VS::CANVAS_ITEM_Z_MIN + i, p_canvas->modulate, p_lights, p_transform); } } else { @@ -440,13 +440,17 @@ void VisualServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point if (p_antialiased) { pline->line_colors.push_back(Color(1, 1, 1, 1)); } - } - if (p_colors.size() == 1) { + } else if (p_colors.size() == 1) { pline->triangle_colors = p_colors; pline->line_colors = p_colors; } else { - pline->triangle_colors.resize(pline->triangles.size()); - pline->line_colors.resize(pline->lines.size()); + if (p_colors.size() != p_points.size()) { + pline->triangle_colors.push_back(p_colors[0]); + pline->line_colors.push_back(p_colors[0]); + } else { + pline->triangle_colors.resize(pline->triangles.size()); + pline->line_colors.resize(pline->lines.size()); + } } for (int i = 0; i < p_points.size(); i++) { @@ -742,7 +746,7 @@ void VisualServerCanvas::canvas_item_add_set_transform(RID p_item, const Transfo canvas_item->commands.push_back(tr); } -void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture, RID p_normal_map, RID p_skeleton) { +void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture, RID p_normal_map) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -752,7 +756,6 @@ void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID m->mesh = p_mesh; m->texture = p_texture; m->normal_map = p_normal_map; - m->skeleton = p_skeleton; canvas_item->commands.push_back(m); } @@ -776,7 +779,7 @@ void VisualServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, canvas_item->commands.push_back(part); } -void VisualServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture, RID p_normal_map, RID p_skeleton) { +void VisualServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture, RID p_normal_map) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -784,7 +787,6 @@ void VisualServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p Item::CommandMultiMesh *mm = memnew(Item::CommandMultiMesh); ERR_FAIL_COND(!mm); mm->multimesh = p_mesh; - mm->skeleton = p_skeleton; mm->texture = p_texture; mm->normal_map = p_normal_map; @@ -826,6 +828,15 @@ void VisualServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, boo canvas_item->z_relative = p_enable; } + +void VisualServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) { + + Item *canvas_item = canvas_item_owner.getornull(p_item); + ERR_FAIL_COND(!canvas_item); + + canvas_item->skeleton = p_skeleton; +} + void VisualServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) { Item *canvas_item = canvas_item_owner.getornull(p_item); diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h index 250ba5cb08..6a5a7623b6 100644 --- a/servers/visual/visual_server_canvas.h +++ b/servers/visual/visual_server_canvas.h @@ -51,6 +51,8 @@ public: Vector<Item *> child_items; + RID skeleton; + Item() { children_order_dirty = true; E = NULL; @@ -182,8 +184,8 @@ public: void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()); void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false); void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()); - void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID(), RID p_skeleton = RID()); - void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID(), RID p_skeleton = RID()); + void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID()); + void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID()); void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal, int p_h_frames, int p_v_frames); void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform); void canvas_item_add_clip_ignore(RID p_item, bool p_ignore); @@ -191,6 +193,7 @@ public: void canvas_item_set_z_index(RID p_item, int p_z); void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable); void canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect); + void canvas_item_attach_skeleton(RID p_item, RID p_skeleton); void canvas_item_clear(RID p_item); void canvas_item_set_draw_index(RID p_item, int p_index); diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 64a3502e40..fca3126604 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -205,4 +205,5 @@ VisualServerRaster::~VisualServerRaster() { memdelete(VSG::canvas); memdelete(VSG::viewport); memdelete(VSG::rasterizer); + memdelete(VSG::scene); } diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index b34fbbdec9..a94e110b5d 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -581,8 +581,8 @@ public: BIND7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID) BIND7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool) BIND8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID) - BIND5(canvas_item_add_mesh, RID, const RID &, RID, RID, RID) - BIND5(canvas_item_add_multimesh, RID, RID, RID, RID, RID) + BIND4(canvas_item_add_mesh, RID, const RID &, RID, RID) + BIND4(canvas_item_add_multimesh, RID, RID, RID, RID) BIND6(canvas_item_add_particles, RID, RID, RID, RID, int, int) BIND2(canvas_item_add_set_transform, RID, const Transform2D &) BIND2(canvas_item_add_clip_ignore, RID, bool) @@ -590,6 +590,7 @@ public: BIND2(canvas_item_set_z_index, RID, int) BIND2(canvas_item_set_z_as_relative_to_parent, RID, bool) BIND3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &) + BIND2(canvas_item_attach_skeleton, RID, RID) BIND1(canvas_item_clear, RID) BIND2(canvas_item_set_draw_index, RID, int) diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 0920fa748b..04dcde1365 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -730,6 +730,11 @@ void VisualServerScene::instance_set_exterior(RID p_instance, bool p_enabled) { } void VisualServerScene::instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) { + Instance *instance = instance_owner.get(p_instance); + ERR_FAIL_COND(!instance); + + instance->extra_margin = p_margin; + _instance_queue_update(instance, true, false); } Vector<ObjectID> VisualServerScene::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const { @@ -3333,6 +3338,7 @@ VisualServerScene::~VisualServerScene() { #ifndef NO_THREADS probe_bake_thread_exit = true; + probe_bake_sem->post(); Thread::wait_to_finish(probe_bake_thread); memdelete(probe_bake_thread); memdelete(probe_bake_sem); diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp index 3eb8953c1f..83e05f6f25 100644 --- a/servers/visual/visual_server_viewport.cpp +++ b/servers/visual/visual_server_viewport.cpp @@ -239,10 +239,9 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E void VisualServerViewport::draw_viewports() { // get our arvr interface in case we need it Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); - if (arvr_interface.is_valid()) { - // update our positioning information as late as possible... - arvr_interface->process(); - } + + // process all our active interfaces + ARVRServer::get_singleton()->_process(); clear_color = GLOBAL_GET("rendering/environment/default_clear_color"); @@ -286,6 +285,9 @@ void VisualServerViewport::draw_viewports() { _draw_viewport(vp, ARVRInterface::EYE_RIGHT); arvr_interface->commit_for_eye(ARVRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect); } + + // and for our frame timing, mark when we've finished commiting our eyes + ARVRServer::get_singleton()->_mark_commit(); } else { VSG::rasterizer->set_current_render_target(vp->render_target); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 5a126fb175..b91f80d137 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -499,8 +499,8 @@ public: FUNC7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID) FUNC7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool) FUNC8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID) - FUNC5(canvas_item_add_mesh, RID, const RID &, RID, RID, RID) - FUNC5(canvas_item_add_multimesh, RID, RID, RID, RID, RID) + FUNC4(canvas_item_add_mesh, RID, const RID &, RID, RID) + FUNC4(canvas_item_add_multimesh, RID, RID, RID, RID) FUNC6(canvas_item_add_particles, RID, RID, RID, RID, int, int) FUNC2(canvas_item_add_set_transform, RID, const Transform2D &) FUNC2(canvas_item_add_clip_ignore, RID, bool) @@ -508,6 +508,7 @@ public: FUNC2(canvas_item_set_z_index, RID, int) FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool) FUNC3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &) + FUNC2(canvas_item_attach_skeleton, RID, RID) FUNC1(canvas_item_clear, RID) FUNC2(canvas_item_set_draw_index, RID, int) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 47577a3359..f8640720cb 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1828,8 +1828,8 @@ void VisualServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_item_add_primitive", "item", "points", "colors", "uvs", "texture", "width", "normal_map"), &VisualServer::canvas_item_add_primitive, DEFVAL(1.0), DEFVAL(RID())); ClassDB::bind_method(D_METHOD("canvas_item_add_polygon", "item", "points", "colors", "uvs", "texture", "normal_map", "antialiased"), &VisualServer::canvas_item_add_polygon, DEFVAL(Vector<Point2>()), DEFVAL(RID()), DEFVAL(RID()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("canvas_item_add_triangle_array", "item", "indices", "points", "colors", "uvs", "texture", "count", "normal_map"), &VisualServer::canvas_item_add_triangle_array, DEFVAL(Vector<Point2>()), DEFVAL(RID()), DEFVAL(-1), DEFVAL(RID())); - ClassDB::bind_method(D_METHOD("canvas_item_add_mesh", "item", "mesh", "skeleton"), &VisualServer::canvas_item_add_mesh, DEFVAL(RID())); - ClassDB::bind_method(D_METHOD("canvas_item_add_multimesh", "item", "mesh", "skeleton"), &VisualServer::canvas_item_add_multimesh, DEFVAL(RID())); + ClassDB::bind_method(D_METHOD("canvas_item_add_mesh", "item", "mesh", "texture", "normal_map"), &VisualServer::canvas_item_add_mesh, DEFVAL(RID())); + ClassDB::bind_method(D_METHOD("canvas_item_add_multimesh", "item", "mesh", "texture", "normal_map"), &VisualServer::canvas_item_add_multimesh, DEFVAL(RID())); ClassDB::bind_method(D_METHOD("canvas_item_add_particles", "item", "particles", "texture", "normal_map", "h_frames", "v_frames"), &VisualServer::canvas_item_add_particles); ClassDB::bind_method(D_METHOD("canvas_item_add_set_transform", "item", "transform"), &VisualServer::canvas_item_add_set_transform); ClassDB::bind_method(D_METHOD("canvas_item_add_clip_ignore", "item", "ignore"), &VisualServer::canvas_item_add_clip_ignore); diff --git a/servers/visual_server.h b/servers/visual_server.h index 521d0aece9..537588fd6f 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -846,8 +846,8 @@ public: virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()) = 0; virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false) = 0; virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()) = 0; - virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID(), RID p_skeleton = RID()) = 0; - virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID(), RID p_skeleton = RID()) = 0; + virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0; + virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0; virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, int p_h_frames, int p_v_frames) = 0; virtual void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) = 0; virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore) = 0; @@ -856,6 +856,8 @@ public: virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) = 0; virtual void canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) = 0; + virtual void canvas_item_attach_skeleton(RID p_item, RID p_skeleton) = 0; + virtual void canvas_item_clear(RID p_item) = 0; virtual void canvas_item_set_draw_index(RID p_item, int p_index) = 0; diff --git a/thirdparty/README.md b/thirdparty/README.md index ff05f3d084..394d6098b0 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -11,6 +11,9 @@ The files were adapted to Godot by removing the dependency on b2Math (replacing it by b2Glue.h) and commenting out some verbose printf calls. Upstream code has not changed in 10 years, no need to keep track of changes. +Important: Some files have Godot-made changes. +They are marked with `// -- GODOT start --` and `// -- GODOT end --` +comments. ## bullet @@ -69,6 +72,9 @@ Files extracted from upstream source: - all .cpp and .h files in EtcLib/ - README.md, LICENSE, AUTHORS +Important: Some files have Godot-made changes. +They are marked with `// -- GODOT start --` and `// -- GODOT end --` +comments. ## fonts @@ -165,6 +171,9 @@ Files extracted from upstream source: TODO. +Important: Some files have Godot-made changes. +They are marked with `// -- GODOT start --` and `// -- GODOT end --` +comments. ## libtheora @@ -225,18 +234,19 @@ changes are marked with `// -- GODOT --` comments. ## libwebsockets - Upstream: https://github.com/warmcat/libwebsockets -- Version: 2.4.1 +- Version: 2.4.2 - License: LGPLv2.1 + static linking exception File extracted from upstream source: -- Everything in `lib/` except `http2/`, `event-libs/`. +- Everything in `lib/` except `minilex.c`, `http2/`, `event-libs/`. - From `misc/` exclude `lws-genhash.c`, `lws-ring.c`, `romfs.{c,h}`, `smtp.c`. - From `plat/` exclude `lws-plat-{esp*,optee}.c`. - From `server/` exclude `access-log.c`, `cgi.c`, `daemonize.c`, `lws-spa.c`, `peer-limits.c`, `rewrite.c` - Also copy `win32helpers/` from `win32port/` -- `mbedtls_wrapper/include/platform/ssl_port.h` has a small change to check for OSX (missing `malloc.h`). +- `mbedtls_wrapper/include/platform/ssl_port.h` has a small change to check for OSX and FreeBSD (missing `malloc.h`). The bug is fixed in upstream master via `LWS_HAVE_MALLOC_H`, but not in the 2.4.1 branch (as the file structure has changed). +- You might need to apply the patch in `thirdparty/lws/mbedtls_verify.diff` (port of PR 1215) to future `2.4.x` releases if it does not get cherry picked. Important: `lws_config.h` and `lws_config_private.h` contains custom Godot build configurations, check them out when updating. @@ -244,12 +254,15 @@ Godot build configurations, check them out when updating. ## mbedTLS - Upstream: https://tls.mbed.org/ -- Version: 2.7.0 +- Version: 2.8.0 - License: Apache 2.0 -File extracted from upstream release tarball `mbedtls-2.7.0-apache.tgz`: -- All `*.h` from `include/mbedtls/` to `thirdparty/include/mbedtls/` -- All `*.c` from `library/` to `thirdparty/library/` +File extracted from upstream release tarball `mbedtls-2.8.0-apache.tgz`: +- All `*.h` from `include/mbedtls/` to `thirdparty/mbedtls/include/mbedtls/` +- All `*.c` from `library/` to `thirdparty/mbedtls/library/` +- In file `thirdparty/mbedtls/library/net_sockets.c` mbedTLS overrides the `_WIN32_WINNT` define. + Be sure to check the Godot addition to only redfine it when undefined or `< 0x0501` (PRed upstream). +- Applied the patch in `thirdparty/mbedtls/1453.diff` (PR 1453). Soon to be merged upstream. Check it out at next update. ## minizip diff --git a/thirdparty/b2d_convexdecomp/b2Polygon.cpp b/thirdparty/b2d_convexdecomp/b2Polygon.cpp index b6ead62c63..c80204ae21 100644 --- a/thirdparty/b2d_convexdecomp/b2Polygon.cpp +++ b/thirdparty/b2d_convexdecomp/b2Polygon.cpp @@ -1342,7 +1342,12 @@ b2Polygon TraceEdge(b2Polygon* p){ if (nodes[j].nConnected == 0) continue; b2Vec2 diff = nodes[i].position - nodes[j].position; if (diff.LengthSquared() <= COLLAPSE_DIST_SQR){ - if (nActive <= 3) return b2Polygon(); + if (nActive <= 3) { + // -- GODOT start -- + delete[] nodes; + // -- GODOT end -- + return b2Polygon(); + } //printf("Found dupe, %d left\n",nActive); --nActive; foundDupe = true; diff --git a/thirdparty/etc2comp/EtcFilter.cpp b/thirdparty/etc2comp/EtcFilter.cpp index bc899a533e..1ec8acdf3f 100644 --- a/thirdparty/etc2comp/EtcFilter.cpp +++ b/thirdparty/etc2comp/EtcFilter.cpp @@ -228,6 +228,9 @@ int FilterTwoPass( RGBCOLOR *pSrcImage, int srcWidth, int srcHeight, pTempImage = (RGBCOLOR *)malloc( destWidth * srcHeight * sizeof(RGBCOLOR) ); if ( pTempImage == NULL ) { + // -- GODOT start -- + free( contrib ); + // -- GODOT end -- return 0; } diff --git a/thirdparty/glad/glad.c b/thirdparty/glad/glad.c index f87ec8cf93..c2aaea2144 100644 --- a/thirdparty/glad/glad.c +++ b/thirdparty/glad/glad.c @@ -1,21 +1,23 @@ /* - OpenGL loader generated by glad 0.1.16a0 on Thu Nov 30 06:21:28 2017. + OpenGL loader generated by glad 0.1.18a0 on Mon Mar 5 18:43:52 2018. Language/Generator: C/C++ Specification: gl APIs: gl=3.3 Profile: compatibility Extensions: - GL_ARB_debug_output + GL_ARB_debug_output, + GL_ARB_framebuffer_object, + GL_EXT_framebuffer_object Loader: True Local files: False Omit khrplatform: False Commandline: - --profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_debug_output" + --profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_debug_output,GL_ARB_framebuffer_object,GL_EXT_framebuffer_object" Online: - http://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_debug_output + http://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_debug_output&extensions=GL_ARB_framebuffer_object&extensions=GL_EXT_framebuffer_object */ #include <stdio.h> @@ -47,8 +49,8 @@ int open_gl(void) { static void close_gl(void) { if(libGL != NULL) { - FreeLibrary(libGL); - libGL = NULL; + FreeLibrary((HMODULE) libGL); + libGL = NULL; } } #else @@ -112,7 +114,7 @@ void* get_proc(const char *namez) { #endif if(result == NULL) { #ifdef _WIN32 - result = (void*)GetProcAddress(libGL, namez); + result = (void*)GetProcAddress((HMODULE) libGL, namez); #else result = dlsym(libGL, namez); #endif @@ -168,7 +170,7 @@ static int get_exts(void) { const char *gl_str_tmp = (const char*)glGetStringi(GL_EXTENSIONS, index); size_t len = strlen(gl_str_tmp); - char *local_str = (char*)malloc((len+1) * sizeof(*exts_i)); + char *local_str = (char*)malloc((len+1) * sizeof(char)); if(local_str != NULL) { #if _MSC_VER >= 1400 strncpy_s(local_str, len+1, gl_str_tmp, len); @@ -971,11 +973,30 @@ PFNGLCOLORPOINTERPROC glad_glColorPointer; PFNGLFRONTFACEPROC glad_glFrontFace; PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; +int GLAD_GL_ARB_framebuffer_object; +int GLAD_GL_EXT_framebuffer_object; int GLAD_GL_ARB_debug_output; PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB; PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB; PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB; PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB; +PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT; +PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT; +PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT; +PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT; +PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT; +PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT; +PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT; +PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT; +PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT; +PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT; +PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT; +PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT; +PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT; +PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT; +PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT; +PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT; static void load_GL_VERSION_1_0(GLADloadproc load) { if(!GLAD_GL_VERSION_1_0) return; glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); @@ -1746,9 +1767,54 @@ static void load_GL_ARB_debug_output(GLADloadproc load) { glad_glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)load("glDebugMessageCallbackARB"); glad_glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC)load("glGetDebugMessageLogARB"); } +static void load_GL_ARB_framebuffer_object(GLADloadproc load) { + if(!GLAD_GL_ARB_framebuffer_object) return; + glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer"); + glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer"); + glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers"); + glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers"); + glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage"); + glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv"); + glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer"); + glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer"); + glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers"); + glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers"); + glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus"); + glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)load("glFramebufferTexture1D"); + glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D"); + glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)load("glFramebufferTexture3D"); + glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer"); + glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv"); + glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer"); +} +static void load_GL_EXT_framebuffer_object(GLADloadproc load) { + if(!GLAD_GL_EXT_framebuffer_object) return; + glad_glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)load("glIsRenderbufferEXT"); + glad_glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)load("glBindRenderbufferEXT"); + glad_glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)load("glDeleteRenderbuffersEXT"); + glad_glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)load("glGenRenderbuffersEXT"); + glad_glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)load("glRenderbufferStorageEXT"); + glad_glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)load("glGetRenderbufferParameterivEXT"); + glad_glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)load("glIsFramebufferEXT"); + glad_glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)load("glBindFramebufferEXT"); + glad_glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)load("glDeleteFramebuffersEXT"); + glad_glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)load("glGenFramebuffersEXT"); + glad_glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)load("glCheckFramebufferStatusEXT"); + glad_glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)load("glFramebufferTexture1DEXT"); + glad_glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)load("glFramebufferTexture2DEXT"); + glad_glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)load("glFramebufferTexture3DEXT"); + glad_glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)load("glFramebufferRenderbufferEXT"); + glad_glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)load("glGetFramebufferAttachmentParameterivEXT"); + glad_glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)load("glGenerateMipmapEXT"); +} static int find_extensionsGL(void) { if (!get_exts()) return 0; GLAD_GL_ARB_debug_output = has_ext("GL_ARB_debug_output"); + GLAD_GL_ARB_framebuffer_object = has_ext("GL_ARB_framebuffer_object"); + GLAD_GL_EXT_framebuffer_object = has_ext("GL_EXT_framebuffer_object"); free_exts(); return 1; } @@ -1828,6 +1894,8 @@ int gladLoadGLLoader(GLADloadproc load) { if (!find_extensionsGL()) return 0; load_GL_ARB_debug_output(load); + load_GL_ARB_framebuffer_object(load); + load_GL_EXT_framebuffer_object(load); return GLVersion.major != 0 || GLVersion.minor != 0; } diff --git a/thirdparty/glad/glad/glad.h b/thirdparty/glad/glad/glad.h index 69413ef65f..9de720fbc2 100644 --- a/thirdparty/glad/glad/glad.h +++ b/thirdparty/glad/glad/glad.h @@ -1,21 +1,23 @@ /* - OpenGL loader generated by glad 0.1.16a0 on Thu Nov 30 06:21:28 2017. + OpenGL loader generated by glad 0.1.18a0 on Mon Mar 5 18:43:52 2018. Language/Generator: C/C++ Specification: gl APIs: gl=3.3 Profile: compatibility Extensions: - GL_ARB_debug_output + GL_ARB_debug_output, + GL_ARB_framebuffer_object, + GL_EXT_framebuffer_object Loader: True Local files: False Omit khrplatform: False Commandline: - --profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_debug_output" + --profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_debug_output,GL_ARB_framebuffer_object,GL_EXT_framebuffer_object" Online: - http://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_debug_output + http://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_debug_output&extensions=GL_ARB_framebuffer_object&extensions=GL_EXT_framebuffer_object */ @@ -3680,6 +3682,57 @@ GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; #define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 #define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 #define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 #ifndef GL_ARB_debug_output #define GL_ARB_debug_output 1 GLAPI int GLAD_GL_ARB_debug_output; @@ -3696,6 +3749,65 @@ typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC)(GLuint count, GLsizei GLAPI PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB; #define glGetDebugMessageLogARB glad_glGetDebugMessageLogARB #endif +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 +GLAPI int GLAD_GL_ARB_framebuffer_object; +#endif +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 1 +GLAPI int GLAD_GL_EXT_framebuffer_object; +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC)(GLuint renderbuffer); +GLAPI PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT; +#define glIsRenderbufferEXT glad_glIsRenderbufferEXT +typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC)(GLenum target, GLuint renderbuffer); +GLAPI PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT; +#define glBindRenderbufferEXT glad_glBindRenderbufferEXT +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC)(GLsizei n, const GLuint *renderbuffers); +GLAPI PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT; +#define glDeleteRenderbuffersEXT glad_glDeleteRenderbuffersEXT +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC)(GLsizei n, GLuint *renderbuffers); +GLAPI PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT; +#define glGenRenderbuffersEXT glad_glGenRenderbuffersEXT +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT; +#define glRenderbufferStorageEXT glad_glRenderbufferStorageEXT +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)(GLenum target, GLenum pname, GLint *params); +GLAPI PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT; +#define glGetRenderbufferParameterivEXT glad_glGetRenderbufferParameterivEXT +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC)(GLuint framebuffer); +GLAPI PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT; +#define glIsFramebufferEXT glad_glIsFramebufferEXT +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC)(GLenum target, GLuint framebuffer); +GLAPI PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT; +#define glBindFramebufferEXT glad_glBindFramebufferEXT +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC)(GLsizei n, const GLuint *framebuffers); +GLAPI PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT; +#define glDeleteFramebuffersEXT glad_glDeleteFramebuffersEXT +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC)(GLsizei n, GLuint *framebuffers); +GLAPI PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT; +#define glGenFramebuffersEXT glad_glGenFramebuffersEXT +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)(GLenum target); +GLAPI PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT; +#define glCheckFramebufferStatusEXT glad_glCheckFramebufferStatusEXT +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT; +#define glFramebufferTexture1DEXT glad_glFramebufferTexture1DEXT +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT; +#define glFramebufferTexture2DEXT glad_glFramebufferTexture2DEXT +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT; +#define glFramebufferTexture3DEXT glad_glFramebufferTexture3DEXT +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT; +#define glFramebufferRenderbufferEXT glad_glFramebufferRenderbufferEXT +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)(GLenum target, GLenum attachment, GLenum pname, GLint *params); +GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT; +#define glGetFramebufferAttachmentParameterivEXT glad_glGetFramebufferAttachmentParameterivEXT +typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC)(GLenum target); +GLAPI PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT; +#define glGenerateMipmapEXT glad_glGenerateMipmapEXT +#endif #ifdef __cplusplus } diff --git a/thirdparty/libsimplewebm/libwebm/README.libvpx b/thirdparty/libsimplewebm/libwebm/README.libvpx index ae62f36525..1aa93b75aa 100644 --- a/thirdparty/libsimplewebm/libwebm/README.libvpx +++ b/thirdparty/libsimplewebm/libwebm/README.libvpx @@ -1,5 +1,5 @@ URL: https://chromium.googlesource.com/webm/libwebm -Version: 32d5ac49414a8914ec1e1f285f3f927c6e8ec29d +Version: d7c62173ff6b4a5e0a2f86683a5b67db98cf09bf License: BSD License File: LICENSE.txt diff --git a/thirdparty/libsimplewebm/libwebm/common/webmids.h b/thirdparty/libsimplewebm/libwebm/common/webmids.h index 32a0c5fb91..89d722a71b 100644 --- a/thirdparty/libsimplewebm/libwebm/common/webmids.h +++ b/thirdparty/libsimplewebm/libwebm/common/webmids.h @@ -124,6 +124,14 @@ enum MkvId { kMkvLuminanceMin = 0x55DA, // end mastering metadata // end colour + // projection + kMkvProjection = 0x7670, + kMkvProjectionType = 0x7671, + kMkvProjectionPrivate = 0x7672, + kMkvProjectionPoseYaw = 0x7673, + kMkvProjectionPosePitch = 0x7674, + kMkvProjectionPoseRoll = 0x7675, + // end projection // audio kMkvAudio = 0xE1, kMkvSamplingFrequency = 0xB5, diff --git a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc index bda67a5758..e7b76f7da1 100644 --- a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc +++ b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.cc @@ -12,51 +12,30 @@ #define MSC_COMPAT #endif -#include <assert.h> -#include <float.h> -#include <limits.h> -#include <math.h> -#include <string.h> +#include <cassert> +#include <cfloat> +#include <climits> +#include <cmath> +#include <cstring> +#include <memory> +#include <new> #include "common/webmids.h" namespace mkvparser { +const long long kStringElementSizeLimit = 20 * 1000 * 1000; const float MasteringMetadata::kValueNotPresent = FLT_MAX; const long long Colour::kValueNotPresent = LLONG_MAX; +const float Projection::kValueNotPresent = FLT_MAX; #ifdef MSC_COMPAT inline bool isnan(double val) { return !!_isnan(val); } inline bool isinf(double val) { return !_finite(val); } +#else +inline bool isnan(double val) { return std::isnan(val); } +inline bool isinf(double val) { return std::isinf(val); } #endif // MSC_COMPAT -template<typename T> -class my_auto_ptr { - my_auto_ptr(const my_auto_ptr &); - T *operator =(const my_auto_ptr &); - - T *m_ptr; -public: - my_auto_ptr(T *ptr) : - m_ptr(ptr) - {} - my_auto_ptr() : - m_ptr(NULL) - {} - ~my_auto_ptr() { - delete m_ptr; - } - - T *release() { - T *ptr = m_ptr; - m_ptr = NULL; - return ptr; - } - - T *operator ->() const { - return m_ptr; - } -}; - IMkvReader::~IMkvReader() {} template <typename Type> @@ -72,7 +51,7 @@ Type* SafeArrayAlloc(unsigned long long num_elements, if (num_bytes != static_cast<size_t>(num_bytes)) return NULL; - return new Type[static_cast<size_t>(num_bytes)]; + return new (std::nothrow) Type[static_cast<size_t>(num_bytes)]; } void GetVersion(int& major, int& minor, int& build, int& revision) { @@ -304,7 +283,7 @@ long UnserializeFloat(IMkvReader* pReader, long long pos, long long size_, result = d; } - if (isinf(result) || isnan(result)) + if (mkvparser::isinf(result) || mkvparser::isnan(result)) return E_FILE_FORMAT_INVALID; return 0; @@ -347,7 +326,7 @@ long UnserializeString(IMkvReader* pReader, long long pos, long long size, delete[] str; str = NULL; - if (size >= LONG_MAX || size < 0) + if (size >= LONG_MAX || size < 0 || size > kStringElementSizeLimit) return E_FILE_FORMAT_INVALID; // +1 for '\0' terminator @@ -818,7 +797,9 @@ long long Segment::CreateInstance(IMkvReader* pReader, long long pos, else if ((pos + size) > total) size = -1; - pSegment = new Segment(pReader, idpos, pos, size); + pSegment = new (std::nothrow) Segment(pReader, idpos, pos, size); + if (pSegment == NULL) + return E_PARSE_FAILED; return 0; // success } @@ -954,7 +935,11 @@ long long Segment::ParseHeaders() { if (m_pInfo) return E_FILE_FORMAT_INVALID; - m_pInfo = new SegmentInfo(this, pos, size, element_start, element_size); + m_pInfo = new (std::nothrow) + SegmentInfo(this, pos, size, element_start, element_size); + + if (m_pInfo == NULL) + return -1; const long status = m_pInfo->Parse(); @@ -964,7 +949,11 @@ long long Segment::ParseHeaders() { if (m_pTracks) return E_FILE_FORMAT_INVALID; - m_pTracks = new Tracks(this, pos, size, element_start, element_size); + m_pTracks = new (std::nothrow) + Tracks(this, pos, size, element_start, element_size); + + if (m_pTracks == NULL) + return -1; const long status = m_pTracks->Parse(); @@ -972,11 +961,19 @@ long long Segment::ParseHeaders() { return status; } else if (id == libwebm::kMkvCues) { if (m_pCues == NULL) { - m_pCues = new Cues(this, pos, size, element_start, element_size); + m_pCues = new (std::nothrow) + Cues(this, pos, size, element_start, element_size); + + if (m_pCues == NULL) + return -1; } } else if (id == libwebm::kMkvSeekHead) { if (m_pSeekHead == NULL) { - m_pSeekHead = new SeekHead(this, pos, size, element_start, element_size); + m_pSeekHead = new (std::nothrow) + SeekHead(this, pos, size, element_start, element_size); + + if (m_pSeekHead == NULL) + return -1; const long status = m_pSeekHead->Parse(); @@ -985,7 +982,11 @@ long long Segment::ParseHeaders() { } } else if (id == libwebm::kMkvChapters) { if (m_pChapters == NULL) { - m_pChapters = new Chapters(this, pos, size, element_start, element_size); + m_pChapters = new (std::nothrow) + Chapters(this, pos, size, element_start, element_size); + + if (m_pChapters == NULL) + return -1; const long status = m_pChapters->Parse(); @@ -994,7 +995,11 @@ long long Segment::ParseHeaders() { } } else if (id == libwebm::kMkvTags) { if (m_pTags == NULL) { - m_pTags = new Tags(this, pos, size, element_start, element_size); + m_pTags = new (std::nothrow) + Tags(this, pos, size, element_start, element_size); + + if (m_pTags == NULL) + return -1; const long status = m_pTags->Parse(); @@ -1136,7 +1141,9 @@ long Segment::DoLoadCluster(long long& pos, long& len) { if (m_pCues == NULL) { const long long element_size = (pos - idpos) + size; - m_pCues = new Cues(this, pos, size, idpos, element_size); + m_pCues = new (std::nothrow) Cues(this, pos, size, idpos, element_size); + if (m_pCues == NULL) + return -1; } m_pos = pos + size; // consume payload @@ -1342,7 +1349,9 @@ bool Segment::AppendCluster(Cluster* pCluster) { if (count >= size) { const long n = (size <= 0) ? 2048 : 2 * size; - Cluster** const qq = new Cluster*[n]; + Cluster** const qq = new (std::nothrow) Cluster*[n]; + if (qq == NULL) + return false; Cluster** q = qq; Cluster** p = m_clusters; @@ -1397,7 +1406,9 @@ bool Segment::PreloadCluster(Cluster* pCluster, ptrdiff_t idx) { if (count >= size) { const long n = (size <= 0) ? 2048 : 2 * size; - Cluster** const qq = new Cluster*[n]; + Cluster** const qq = new (std::nothrow) Cluster*[n]; + if (qq == NULL) + return false; Cluster** q = qq; Cluster** p = m_clusters; @@ -1466,6 +1477,8 @@ long Segment::Load() { } } +SeekHead::Entry::Entry() : id(0), pos(0), element_start(0), element_size(0) {} + SeekHead::SeekHead(Segment* pSegment, long long start, long long size_, long long element_start, long long element_size) : m_pSegment(pSegment), @@ -1516,9 +1529,19 @@ long SeekHead::Parse() { if (pos != stop) return E_FILE_FORMAT_INVALID; - m_entries = new Entry[entry_count]; + if (entry_count > 0) { + m_entries = new (std::nothrow) Entry[entry_count]; - m_void_elements = new VoidElement[void_element_count]; + if (m_entries == NULL) + return -1; + } + + if (void_element_count > 0) { + m_void_elements = new (std::nothrow) VoidElement[void_element_count]; + + if (m_void_elements == NULL) + return -1; + } // now parse the entries and void elements @@ -1537,14 +1560,14 @@ long SeekHead::Parse() { if (status < 0) // error return status; - if (id == libwebm::kMkvSeek) { + if (id == libwebm::kMkvSeek && entry_count > 0) { if (ParseEntry(pReader, pos, size, pEntry)) { Entry& e = *pEntry++; e.element_start = idpos; e.element_size = (pos + size) - idpos; } - } else if (id == libwebm::kMkvVoid) { + } else if (id == libwebm::kMkvVoid && void_element_count > 0) { VoidElement& e = *pVoidElement++; e.element_start = idpos; @@ -1706,7 +1729,10 @@ long Segment::ParseCues(long long off, long long& pos, long& len) { const long long element_size = element_stop - element_start; - m_pCues = new Cues(this, pos, size, element_start, element_size); + m_pCues = + new (std::nothrow) Cues(this, pos, size, element_start, element_size); + if (m_pCues == NULL) + return -1; return 0; // success } @@ -1748,18 +1774,7 @@ bool SeekHead::ParseEntry(IMkvReader* pReader, long long start, long long size_, if ((pos + seekIdSize) > stop) return false; - // Note that the SeekId payload really is serialized - // as a "Matroska integer", not as a plain binary value. - // In fact, Matroska requires that ID values in the - // stream exactly match the binary representation as listed - // in the Matroska specification. - // - // This parser is more liberal, and permits IDs to have - // any width. (This could make the representation in the stream - // different from what's in the spec, but it doesn't matter here, - // since we always normalize "Matroska integer" values.) - - pEntry->id = ReadUInt(pReader, pos, len); // payload + pEntry->id = ReadID(pReader, pos, len); // payload if (pEntry->id <= 0) return false; @@ -1898,7 +1913,9 @@ bool Cues::PreloadCuePoint(long& cue_points_size, long long pos) const { if (m_preload_count >= cue_points_size) { const long n = (cue_points_size <= 0) ? 2048 : 2 * cue_points_size; - CuePoint** const qq = new CuePoint*[n]; + CuePoint** const qq = new (std::nothrow) CuePoint*[n]; + if (qq == NULL) + return false; CuePoint** q = qq; // beginning of target @@ -1914,7 +1931,9 @@ bool Cues::PreloadCuePoint(long& cue_points_size, long long pos) const { cue_points_size = n; } - CuePoint* const pCP = new CuePoint(m_preload_count, pos); + CuePoint* const pCP = new (std::nothrow) CuePoint(m_preload_count, pos); + if (pCP == NULL) + return false; m_cue_points[m_preload_count++] = pCP; return true; @@ -2320,7 +2339,9 @@ bool CuePoint::Load(IMkvReader* pReader) { // << " timecode=" << m_timecode // << endl; - m_track_positions = new TrackPosition[m_track_positions_count]; + m_track_positions = new (std::nothrow) TrackPosition[m_track_positions_count]; + if (m_track_positions == NULL) + return false; // Now parse track positions @@ -2410,7 +2431,9 @@ bool CuePoint::TrackPosition::Parse(IMkvReader* pReader, long long start_, } const CuePoint::TrackPosition* CuePoint::Find(const Track* pTrack) const { - assert(pTrack); + if (pTrack == NULL) { + return NULL; + } const long long n = pTrack->GetNumber(); @@ -2915,7 +2938,10 @@ long Segment::DoParseNext(const Cluster*& pResult, long long& pos, long& len) { const long long element_size = element_stop - element_start; if (m_pCues == NULL) { - m_pCues = new Cues(this, pos, size, element_start, element_size); + m_pCues = new (std::nothrow) + Cues(this, pos, size, element_start, element_size); + if (m_pCues == NULL) + return false; } pos += size; // consume payload @@ -3266,7 +3292,10 @@ bool Chapters::ExpandEditionsArray() { const int size = (m_editions_size == 0) ? 1 : 2 * m_editions_size; - Edition* const editions = new Edition[size]; + Edition* const editions = new (std::nothrow) Edition[size]; + + if (editions == NULL) + return false; for (int idx = 0; idx < m_editions_count; ++idx) { m_editions[idx].ShallowCopy(editions[idx]); @@ -3378,7 +3407,10 @@ bool Chapters::Edition::ExpandAtomsArray() { const int size = (m_atoms_size == 0) ? 1 : 2 * m_atoms_size; - Atom* const atoms = new Atom[size]; + Atom* const atoms = new (std::nothrow) Atom[size]; + + if (atoms == NULL) + return false; for (int idx = 0; idx < m_atoms_count; ++idx) { m_atoms[idx].ShallowCopy(atoms[idx]); @@ -3563,7 +3595,10 @@ bool Chapters::Atom::ExpandDisplaysArray() { const int size = (m_displays_size == 0) ? 1 : 2 * m_displays_size; - Display* const displays = new Display[size]; + Display* const displays = new (std::nothrow) Display[size]; + + if (displays == NULL) + return false; for (int idx = 0; idx < m_displays_count; ++idx) { m_displays[idx].ShallowCopy(displays[idx]); @@ -3723,7 +3758,10 @@ bool Tags::ExpandTagsArray() { const int size = (m_tags_size == 0) ? 1 : 2 * m_tags_size; - Tag* const tags = new Tag[size]; + Tag* const tags = new (std::nothrow) Tag[size]; + + if (tags == NULL) + return false; for (int idx = 0; idx < m_tags_count; ++idx) { m_tags[idx].ShallowCopy(tags[idx]); @@ -3834,7 +3872,10 @@ bool Tags::Tag::ExpandSimpleTagsArray() { const int size = (m_simple_tags_size == 0) ? 1 : 2 * m_simple_tags_size; - SimpleTag* const displays = new SimpleTag[size]; + SimpleTag* const displays = new (std::nothrow) SimpleTag[size]; + + if (displays == NULL) + return false; for (int idx = 0; idx < m_simple_tags_count; ++idx) { m_simple_tags[idx].ShallowCopy(displays[idx]); @@ -3992,7 +4033,7 @@ long SegmentInfo::Parse() { } const double rollover_check = m_duration * m_timecodeScale; - if (rollover_check > LLONG_MAX) + if (rollover_check > static_cast<double>(LLONG_MAX)) return E_FILE_FORMAT_INVALID; if (pos != stop) @@ -4083,7 +4124,7 @@ ContentEncoding::~ContentEncoding() { } const ContentEncoding::ContentCompression* - ContentEncoding::GetCompressionByIndex(unsigned long idx) const { +ContentEncoding::GetCompressionByIndex(unsigned long idx) const { const ptrdiff_t count = compression_entries_end_ - compression_entries_; assert(count >= 0); @@ -4179,12 +4220,20 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size, return -1; if (compression_count > 0) { - compression_entries_ = new ContentCompression*[compression_count]; + compression_entries_ = + new (std::nothrow) ContentCompression*[compression_count]; + if (!compression_entries_) + return -1; compression_entries_end_ = compression_entries_; } if (encryption_count > 0) { - encryption_entries_ = new ContentEncryption*[encryption_count]; + encryption_entries_ = + new (std::nothrow) ContentEncryption*[encryption_count]; + if (!encryption_entries_) { + delete[] compression_entries_; + return -1; + } encryption_entries_end_ = encryption_entries_; } @@ -4204,7 +4253,10 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size, } else if (id == libwebm::kMkvContentEncodingType) { encoding_type_ = UnserializeUInt(pReader, pos, size); } else if (id == libwebm::kMkvContentCompression) { - ContentCompression* const compression = new ContentCompression(); + ContentCompression* const compression = + new (std::nothrow) ContentCompression(); + if (!compression) + return -1; status = ParseCompressionEntry(pos, size, pReader, compression); if (status) { @@ -4213,7 +4265,10 @@ long ContentEncoding::ParseContentEncodingEntry(long long start, long long size, } *compression_entries_end_++ = compression; } else if (id == libwebm::kMkvContentEncryption) { - ContentEncryption* const encryption = new ContentEncryption(); + ContentEncryption* const encryption = + new (std::nothrow) ContentEncryption(); + if (!encryption) + return -1; status = ParseEncryptionEntry(pos, size, pReader, encryption); if (status) { @@ -4419,7 +4474,11 @@ long Track::Create(Segment* pSegment, const Info& info, long long element_start, if (pResult) return -1; - Track* const pTrack = new Track(pSegment, element_start, element_size); + Track* const pTrack = + new (std::nothrow) Track(pSegment, element_start, element_size); + + if (pTrack == NULL) + return -1; // generic error const int status = info.Copy(pTrack->m_info); @@ -4871,7 +4930,10 @@ long Track::ParseContentEncodingsEntry(long long start, long long size) { if (count <= 0) return -1; - content_encoding_entries_ = new ContentEncoding*[count]; + content_encoding_entries_ = new (std::nothrow) ContentEncoding*[count]; + if (!content_encoding_entries_) + return -1; + content_encoding_entries_end_ = content_encoding_entries_; pos = start; @@ -4883,7 +4945,10 @@ long Track::ParseContentEncodingsEntry(long long start, long long size) { // pos now designates start of element if (id == libwebm::kMkvContentEncoding) { - ContentEncoding* const content_encoding = new ContentEncoding(); + ContentEncoding* const content_encoding = + new (std::nothrow) ContentEncoding(); + if (!content_encoding) + return -1; status = content_encoding->ParseContentEncodingEntry(pos, size, pReader); if (status) { @@ -4917,20 +4982,27 @@ bool PrimaryChromaticity::Parse(IMkvReader* reader, long long read_pos, if (!reader) return false; - my_auto_ptr<PrimaryChromaticity> chromaticity_ptr(*chromaticity ? *chromaticity : new PrimaryChromaticity()); + if (!*chromaticity) + *chromaticity = new PrimaryChromaticity(); - float* value = is_x ? &chromaticity_ptr->x : &chromaticity_ptr->y; + if (!*chromaticity) + return false; + + PrimaryChromaticity* pc = *chromaticity; + float* value = is_x ? &pc->x : &pc->y; double parser_value = 0; - const long long value_parse_status = + const long long parse_status = UnserializeFloat(reader, read_pos, value_size, parser_value); - *value = static_cast<float>(parser_value); - - if (value_parse_status < 0 || *value < 0.0 || *value > 1.0) + // Valid range is [0, 1]. Make sure the double is representable as a float + // before casting. + if (parse_status < 0 || parser_value < 0.0 || parser_value > 1.0 || + (parser_value > 0.0 && parser_value < FLT_MIN)) return false; - *chromaticity = chromaticity_ptr.release(); + *value = static_cast<float>(parser_value); + return true; } @@ -4939,7 +5011,9 @@ bool MasteringMetadata::Parse(IMkvReader* reader, long long mm_start, if (!reader || *mm) return false; - my_auto_ptr<MasteringMetadata> mm_ptr(new MasteringMetadata()); + std::unique_ptr<MasteringMetadata> mm_ptr(new MasteringMetadata()); + if (!mm_ptr.get()) + return false; const long long mm_end = mm_start + mm_size; long long read_pos = mm_start; @@ -4957,6 +5031,10 @@ bool MasteringMetadata::Parse(IMkvReader* reader, long long mm_start, double value = 0; const long long value_parse_status = UnserializeFloat(reader, read_pos, child_size, value); + if (value < -FLT_MAX || value > FLT_MAX || + (value > 0.0 && value < FLT_MIN)) { + return false; + } mm_ptr->luminance_max = static_cast<float>(value); if (value_parse_status < 0 || mm_ptr->luminance_max < 0.0 || mm_ptr->luminance_max > 9999.99) { @@ -4966,6 +5044,10 @@ bool MasteringMetadata::Parse(IMkvReader* reader, long long mm_start, double value = 0; const long long value_parse_status = UnserializeFloat(reader, read_pos, child_size, value); + if (value < -FLT_MAX || value > FLT_MAX || + (value > 0.0 && value < FLT_MIN)) { + return false; + } mm_ptr->luminance_min = static_cast<float>(value); if (value_parse_status < 0 || mm_ptr->luminance_min < 0.0 || mm_ptr->luminance_min > 999.9999) { @@ -5018,7 +5100,9 @@ bool Colour::Parse(IMkvReader* reader, long long colour_start, if (!reader || *colour) return false; - my_auto_ptr<Colour> colour_ptr(new Colour()); + std::unique_ptr<Colour> colour_ptr(new Colour()); + if (!colour_ptr.get()) + return false; const long long colour_end = colour_start + colour_size; long long read_pos = colour_start; @@ -5109,11 +5193,94 @@ bool Colour::Parse(IMkvReader* reader, long long colour_start, return true; } +bool Projection::Parse(IMkvReader* reader, long long start, long long size, + Projection** projection) { + if (!reader || *projection) + return false; + + std::unique_ptr<Projection> projection_ptr(new Projection()); + if (!projection_ptr.get()) + return false; + + const long long end = start + size; + long long read_pos = start; + + while (read_pos < end) { + long long child_id = 0; + long long child_size = 0; + + const long long status = + ParseElementHeader(reader, read_pos, end, child_id, child_size); + if (status < 0) + return false; + + if (child_id == libwebm::kMkvProjectionType) { + long long projection_type = kTypeNotPresent; + projection_type = UnserializeUInt(reader, read_pos, child_size); + if (projection_type < 0) + return false; + + projection_ptr->type = static_cast<ProjectionType>(projection_type); + } else if (child_id == libwebm::kMkvProjectionPrivate) { + unsigned char* data = SafeArrayAlloc<unsigned char>(1, child_size); + + if (data == NULL) + return false; + + const int status = + reader->Read(read_pos, static_cast<long>(child_size), data); + + if (status) { + delete[] data; + return false; + } + + projection_ptr->private_data = data; + projection_ptr->private_data_length = static_cast<size_t>(child_size); + } else { + double value = 0; + const long long value_parse_status = + UnserializeFloat(reader, read_pos, child_size, value); + // Make sure value is representable as a float before casting. + if (value_parse_status < 0 || value < -FLT_MAX || value > FLT_MAX || + (value > 0.0 && value < FLT_MIN)) { + return false; + } + + switch (child_id) { + case libwebm::kMkvProjectionPoseYaw: + projection_ptr->pose_yaw = static_cast<float>(value); + break; + case libwebm::kMkvProjectionPosePitch: + projection_ptr->pose_pitch = static_cast<float>(value); + break; + case libwebm::kMkvProjectionPoseRoll: + projection_ptr->pose_roll = static_cast<float>(value); + break; + default: + return false; + } + } + + read_pos += child_size; + if (read_pos > end) + return false; + } + + *projection = projection_ptr.release(); + return true; +} + VideoTrack::VideoTrack(Segment* pSegment, long long element_start, long long element_size) - : Track(pSegment, element_start, element_size), m_colour(NULL) {} + : Track(pSegment, element_start, element_size), + m_colour(NULL), + m_projection(NULL) {} -VideoTrack::~VideoTrack() { delete m_colour; } +VideoTrack::~VideoTrack() { + delete m_colour; + delete m_projection; +} long VideoTrack::Parse(Segment* pSegment, const Info& info, long long element_start, long long element_size, @@ -5145,6 +5312,7 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info, const long long stop = pos + s.size; Colour* colour = NULL; + Projection* projection = NULL; while (pos < stop) { long long id, size; @@ -5195,6 +5363,9 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info, } else if (id == libwebm::kMkvColour) { if (!Colour::Parse(pReader, pos, size, &colour)) return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvProjection) { + if (!Projection::Parse(pReader, pos, size, &projection)) + return E_FILE_FORMAT_INVALID; } pos += size; // consume payload @@ -5205,7 +5376,11 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info, if (pos != stop) return E_FILE_FORMAT_INVALID; - VideoTrack* const pTrack = new VideoTrack(pSegment, element_start, element_size); + VideoTrack* const pTrack = + new (std::nothrow) VideoTrack(pSegment, element_start, element_size); + + if (pTrack == NULL) + return -1; // generic error const int status = info.Copy(pTrack->m_info); @@ -5222,6 +5397,7 @@ long VideoTrack::Parse(Segment* pSegment, const Info& info, pTrack->m_stereo_mode = stereo_mode; pTrack->m_rate = rate; pTrack->m_colour = colour; + pTrack->m_projection = projection; pResult = pTrack; return 0; // success @@ -5322,6 +5498,8 @@ long VideoTrack::Seek(long long time_ns, const BlockEntry*& pResult) const { Colour* VideoTrack::GetColour() const { return m_colour; } +Projection* VideoTrack::GetProjection() const { return m_projection; } + long long VideoTrack::GetWidth() const { return m_width; } long long VideoTrack::GetHeight() const { return m_height; } @@ -5404,7 +5582,11 @@ long AudioTrack::Parse(Segment* pSegment, const Info& info, if (pos != stop) return E_FILE_FORMAT_INVALID; - AudioTrack* const pTrack = new AudioTrack(pSegment, element_start, element_size); + AudioTrack* const pTrack = + new (std::nothrow) AudioTrack(pSegment, element_start, element_size); + + if (pTrack == NULL) + return -1; // generic error const int status = info.Copy(pTrack->m_info); @@ -5472,7 +5654,11 @@ long Tracks::Parse() { if (count <= 0) return 0; // success - m_trackEntries = new Track*[count]; + m_trackEntries = new (std::nothrow) Track*[count]; + + if (m_trackEntries == NULL) + return -1; + m_trackEntriesEnd = m_trackEntries; pos = m_start; @@ -6575,7 +6761,10 @@ Cluster* Cluster::Create(Segment* pSegment, long idx, long long off) { const long long element_start = pSegment->m_start + off; - return new Cluster(pSegment, idx, element_start); + Cluster* const pCluster = + new (std::nothrow) Cluster(pSegment, idx, element_start); + + return pCluster; } Cluster::Cluster() @@ -6604,8 +6793,10 @@ Cluster::Cluster(Segment* pSegment, long idx, long long element_start {} Cluster::~Cluster() { - if (m_entries_count <= 0) + if (m_entries_count <= 0) { + delete[] m_entries; return; + } BlockEntry** i = m_entries; BlockEntry** const j = m_entries + m_entries_count; @@ -6918,7 +7109,9 @@ long Cluster::CreateBlock(long long id, assert(m_entries_size == 0); m_entries_size = 1024; - m_entries = new BlockEntry*[m_entries_size]; + m_entries = new (std::nothrow) BlockEntry*[m_entries_size]; + if (m_entries == NULL) + return -1; m_entries_count = 0; } else { @@ -6929,7 +7122,9 @@ long Cluster::CreateBlock(long long id, if (m_entries_count >= m_entries_size) { const long entries_size = 2 * m_entries_size; - BlockEntry** const entries = new BlockEntry*[entries_size]; + BlockEntry** const entries = new (std::nothrow) BlockEntry*[entries_size]; + if (entries == NULL) + return -1; BlockEntry** src = m_entries; BlockEntry** const src_end = src + m_entries_count; @@ -7038,7 +7233,11 @@ long Cluster::CreateBlockGroup(long long start_offset, long long size, BlockEntry** const ppEntry = m_entries + idx; BlockEntry*& pEntry = *ppEntry; - pEntry = new BlockGroup(this, idx, bpos, bsize, prev, next, duration, discard_padding); + pEntry = new (std::nothrow) + BlockGroup(this, idx, bpos, bsize, prev, next, duration, discard_padding); + + if (pEntry == NULL) + return -1; // generic error BlockGroup* const p = static_cast<BlockGroup*>(pEntry); @@ -7066,7 +7265,10 @@ long Cluster::CreateSimpleBlock(long long st, long long sz) { BlockEntry** const ppEntry = m_entries + idx; BlockEntry*& pEntry = *ppEntry; - pEntry = new SimpleBlock(this, idx, st, sz); + pEntry = new (std::nothrow) SimpleBlock(this, idx, st, sz); + + if (pEntry == NULL) + return -1; // generic error SimpleBlock* const p = static_cast<SimpleBlock*>(pEntry); @@ -7461,7 +7663,9 @@ long Block::Parse(const Cluster* pCluster) { return E_FILE_FORMAT_INVALID; m_frame_count = 1; - m_frames = new Frame[m_frame_count]; + m_frames = new (std::nothrow) Frame[m_frame_count]; + if (m_frames == NULL) + return -1; Frame& f = m_frames[0]; f.pos = pos; @@ -7492,7 +7696,9 @@ long Block::Parse(const Cluster* pCluster) { m_frame_count = int(biased_count) + 1; - m_frames = new Frame[m_frame_count]; + m_frames = new (std::nothrow) Frame[m_frame_count]; + if (m_frames == NULL) + return -1; if (!m_frames) return E_FILE_FORMAT_INVALID; @@ -7701,6 +7907,10 @@ long Block::Parse(const Cluster* pCluster) { return E_FILE_FORMAT_INVALID; curr.len = static_cast<long>(frame_size); + // Check if size + curr.len could overflow. + if (size > LLONG_MAX - curr.len) { + return E_FILE_FORMAT_INVALID; + } size += curr.len; // contribution of this frame --frame_count; @@ -7741,7 +7951,6 @@ long Block::Parse(const Cluster* pCluster) { pf = m_frames; while (pf != pf_end) { Frame& f = *pf++; - assert((pos + f.len) <= stop); if ((pos + f.len) > stop) return E_FILE_FORMAT_INVALID; @@ -7763,6 +7972,11 @@ long long Block::GetTimeCode(const Cluster* pCluster) const { const long long tc0 = pCluster->GetTimeCode(); assert(tc0 >= 0); + // Check if tc0 + m_timecode would overflow. + if (tc0 < 0 || LLONG_MAX - tc0 < m_timecode) { + return -1; + } + const long long tc = tc0 + m_timecode; return tc; // unscaled timecode units @@ -7780,6 +7994,10 @@ long long Block::GetTime(const Cluster* pCluster) const { const long long scale = pInfo->GetTimeCodeScale(); assert(scale >= 1); + // Check if tc * scale could overflow. + if (tc != 0 && scale > LLONG_MAX / tc) { + return -1; + } const long long ns = tc * scale; return ns; diff --git a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.h b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.h index 1ef274b162..6dce7e50ba 100644 --- a/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.h +++ b/thirdparty/libsimplewebm/libwebm/mkvparser/mkvparser.h @@ -8,7 +8,7 @@ #ifndef MKVPARSER_MKVPARSER_H_ #define MKVPARSER_MKVPARSER_H_ -#include <stddef.h> +#include <cstddef> namespace mkvparser { @@ -21,6 +21,7 @@ class IMkvReader { virtual int Read(long long pos, long len, unsigned char* buf) = 0; virtual int Length(long long* total, long long* available) = 0; + public: virtual ~IMkvReader(); }; @@ -472,6 +473,34 @@ struct Colour { MasteringMetadata* mastering_metadata; }; +struct Projection { + enum ProjectionType { + kTypeNotPresent = -1, + kRectangular = 0, + kEquirectangular = 1, + kCubeMap = 2, + kMesh = 3, + }; + static const float kValueNotPresent; + Projection() + : type(kTypeNotPresent), + private_data(NULL), + private_data_length(0), + pose_yaw(kValueNotPresent), + pose_pitch(kValueNotPresent), + pose_roll(kValueNotPresent) {} + ~Projection() { delete[] private_data; } + static bool Parse(IMkvReader* reader, long long element_start, + long long element_size, Projection** projection); + + ProjectionType type; + unsigned char* private_data; + size_t private_data_length; + float pose_yaw; + float pose_pitch; + float pose_roll; +}; + class VideoTrack : public Track { VideoTrack(const VideoTrack&); VideoTrack& operator=(const VideoTrack&); @@ -496,6 +525,8 @@ class VideoTrack : public Track { Colour* GetColour() const; + Projection* GetProjection() const; + private: long long m_width; long long m_height; @@ -507,6 +538,7 @@ class VideoTrack : public Track { double m_rate; Colour* m_colour; + Projection* m_projection; }; class AudioTrack : public Track { @@ -812,6 +844,8 @@ class SeekHead { long Parse(); struct Entry { + Entry(); + // the SeekHead entry payload long long id; long long pos; diff --git a/thirdparty/lws/client/client.c b/thirdparty/lws/client/client.c index 20450aa923..ded4e4bf0b 100644 --- a/thirdparty/lws/client/client.c +++ b/thirdparty/lws/client/client.c @@ -258,9 +258,10 @@ start_ws_handshake: #ifdef LWS_OPENSSL_SUPPORT /* we can retry this... just cook the SSL BIO the first time */ - if (wsi->use_ssl && !wsi->ssl) { - if (lws_ssl_client_bio_create(wsi)) - return -1; + if (wsi->use_ssl && !wsi->ssl && + lws_ssl_client_bio_create(wsi) < 0) { + cce = "bio_create failed"; + goto bail3; } if (wsi->use_ssl) { @@ -727,9 +728,10 @@ lws_client_interpret_server_handshake(struct lws *wsi) return 0; } - if (lws_hdr_total_length(wsi, WSI_TOKEN_ACCEPT) == 0) { - lwsl_info("no ACCEPT\n"); - cce = "HS: ACCEPT missing"; + if (p && !strncmp(p, "401", 3)) { + lwsl_warn( + "lws_client_handshake: got bad HTTP response '%s'\n", p); + cce = "HS: ws upgrade unauthorized"; goto bail3; } @@ -740,6 +742,12 @@ lws_client_interpret_server_handshake(struct lws *wsi) goto bail3; } + if (lws_hdr_total_length(wsi, WSI_TOKEN_ACCEPT) == 0) { + lwsl_info("no ACCEPT\n"); + cce = "HS: ACCEPT missing"; + goto bail3; + } + p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE); if (!p) { lwsl_info("no UPGRADE\n"); diff --git a/thirdparty/lws/client/ssl-client.c b/thirdparty/lws/client/ssl-client.c index b69fd2da30..962c6e3cb5 100644 --- a/thirdparty/lws/client/ssl-client.c +++ b/thirdparty/lws/client/ssl-client.c @@ -176,11 +176,7 @@ lws_ssl_client_bio_create(struct lws *wsi) #endif #else #if defined(LWS_WITH_MBEDTLS) - if (wsi->vhost->x509_client_CA) - SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, OpenSSL_client_verify_callback); - else - SSL_set_verify(wsi->ssl, SSL_VERIFY_NONE, OpenSSL_client_verify_callback); - + SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, OpenSSL_client_verify_callback); #else #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME SSL_set_tlsext_host_name(wsi->ssl, hostname); @@ -284,9 +280,13 @@ some_wait: char *p = (char *)&pt->serv_buf[0]; char *sb = p; - lwsl_err("ssl hs1 error, X509_V_ERR = %d: %s\n", - n, ERR_error_string(n, sb)); + lwsl_err("ssl hs1 error, X509_V_ERR = %d: errno %d: %s\n", + n, errno, ERR_error_string(n, sb)); lws_ssl_elaborate_error(); +#if defined(LWS_WITH_MBEDTLS) + if (n == SSL_ERROR_SYSCALL) + return -1; +#endif } n = -1; diff --git a/thirdparty/lws/context.c b/thirdparty/lws/context.c index f67476b1e3..9f221f50f1 100644 --- a/thirdparty/lws/context.c +++ b/thirdparty/lws/context.c @@ -1621,7 +1621,7 @@ lws_context_destroy2(struct lws_context *context) lws_check_deferred_free(context, 1); #if LWS_MAX_SMP > 1 - pthread_mutex_destroy(&context->lock, NULL); + pthread_mutex_destroy(&context->lock); #endif lws_free(context); diff --git a/thirdparty/lws/libwebsockets.c b/thirdparty/lws/libwebsockets.c index 50f975d21e..8fe0854041 100644 --- a/thirdparty/lws/libwebsockets.c +++ b/thirdparty/lws/libwebsockets.c @@ -482,8 +482,9 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason) wsi->mode == LWSCM_WSCL_ISSUE_HANDSHAKE) goto just_kill_connection; - if (wsi->mode == LWSCM_HTTP_SERVING || - wsi->mode == LWSCM_HTTP2_SERVING) { + if (!wsi->told_user_closed && + (wsi->mode == LWSCM_HTTP_SERVING || + wsi->mode == LWSCM_HTTP2_SERVING)) { if (wsi->user_space) wsi->vhost->protocols->callback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL, @@ -583,7 +584,7 @@ just_kill_connection: lws_remove_child_from_any_parent(wsi); n = 0; - if (wsi->user_space) { + if (!wsi->told_user_closed && wsi->user_space) { lwsl_debug("%s: %p: DROP_PROTOCOL %s\n", __func__, wsi, wsi->protocol->name); wsi->protocol->callback(wsi, @@ -656,8 +657,10 @@ just_kill_connection: __func__, wsi, (int)(long)wsi->desc.sockfd, wsi->state); if (!wsi->socket_is_permanently_unusable && - lws_sockfd_valid(wsi->desc.sockfd)) + lws_sockfd_valid(wsi->desc.sockfd)) { + wsi->socket_is_permanently_unusable = 1; n = shutdown(wsi->desc.sockfd, SHUT_WR); + } } if (n) lwsl_debug("closing: shutdown (state %d) ret %d\n", diff --git a/thirdparty/lws/libwebsockets.h b/thirdparty/lws/libwebsockets.h index ef996c5d78..460c732602 100644 --- a/thirdparty/lws/libwebsockets.h +++ b/thirdparty/lws/libwebsockets.h @@ -1073,7 +1073,7 @@ enum lws_callback_reasons { LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS = 22, /**< if configured for * including OpenSSL support, this callback allows your user code - * to load extra certifcates into the server which allow it to + * to load extra certificates into the server which allow it to * verify the validity of certificates returned by clients. user * is the server's OpenSSL SSL_CTX* */ LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION = 23, @@ -4013,9 +4013,6 @@ lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs); #if !defined(LWS_SIZEOFPTR) #define LWS_SIZEOFPTR (sizeof (void *)) #endif -#if !defined(u_int64_t) -#define u_int64_t unsigned long long -#endif #if defined(__x86_64__) #define _LWS_PAD_SIZE 16 /* Intel recommended for best performance */ @@ -4808,7 +4805,7 @@ LWS_VISIBLE LWS_EXTERN unsigned long lws_now_secs(void); /** - * lws_get_context - Allow geting lws_context from a Websocket connection + * lws_get_context - Allow getting lws_context from a Websocket connection * instance * * With this function, users can access context in the callback function. diff --git a/thirdparty/lws/lws_config.h b/thirdparty/lws/lws_config.h index 3a918747b1..6005d94ec6 100644 --- a/thirdparty/lws/lws_config.h +++ b/thirdparty/lws/lws_config.h @@ -1,5 +1,10 @@ /* lws_config.h Generated from lws_config.h.in */ -#include "lws_config_private.h" + +/* GODOT ADDITION */ +#ifndef DEBUG_ENABLED +#define LWS_WITH_NO_LOGS +#endif +/* END GODOT ADDITION */ #ifndef NDEBUG #ifndef _DEBUG @@ -25,54 +30,45 @@ /* #undef LWS_WITH_PLUGINS */ /* #undef LWS_WITH_NO_LOGS */ -#ifndef DEBUG_ENABLED -#define LWS_WITH_NO_LOGS -#endif /* The Libwebsocket version */ -#define LWS_LIBRARY_VERSION "2.4.1" +#define LWS_LIBRARY_VERSION "2.4.2" #define LWS_LIBRARY_VERSION_MAJOR 2 #define LWS_LIBRARY_VERSION_MINOR 4 -#define LWS_LIBRARY_VERSION_PATCH 1 +#define LWS_LIBRARY_VERSION_PATCH 2 /* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */ #define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR*1000000)+(LWS_LIBRARY_VERSION_MINOR*1000)+LWS_LIBRARY_VERSION_PATCH /* The current git commit hash that we're building from */ -#define LWS_BUILD_HASH "55f97b7806e07db2d4c8a158172cd309d0faf450" +#define LWS_BUILD_HASH "8964ce9db75a98e463dfafd2e89f2bc8a95ec6ed" /* Build with OpenSSL support */ #define LWS_OPENSSL_SUPPORT /* The client should load and trust CA root certs it finds in the OS */ -#define LWS_SSL_CLIENT_USE_OS_CA_CERTS +/* #undef LWS_SSL_CLIENT_USE_OS_CA_CERTS */ /* Sets the path where the client certs should be installed. */ -#define LWS_OPENSSL_CLIENT_CERTS "../share" +/* #undef LWS_OPENSSL_CLIENT_CERTS "../share" */ /* Turn off websocket extensions */ /* #undef LWS_NO_EXTENSIONS */ /* Enable libev io loop */ /* #undef LWS_WITH_LIBEV */ -#undef LWS_WITH_LIBEV /* Enable libuv io loop */ /* #undef LWS_WITH_LIBUV */ -#undef LWS_WITH_LIBUV /* Enable libevent io loop */ /* #undef LWS_WITH_LIBEVENT */ -#undef LWS_WITH_LIBEVENT /* Build with support for ipv6 */ /* #undef LWS_WITH_IPV6 */ /* Build with support for UNIX domain socket */ /* #undef LWS_WITH_UNIX_SOCK */ -#ifdef WINDOWS_ENABLED -#undef LWS_USE_UNIX_SOCK -#endif /* Build with support for HTTP2 */ /* #undef LWS_WITH_HTTP2 */ @@ -100,7 +96,7 @@ /* SSL server using ECDH certificate */ /* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */ -#define LWS_HAVE_SSL_CTX_set1_param +/* #undef LWS_HAVE_SSL_CTX_set1_param */ #define LWS_HAVE_X509_VERIFY_PARAM_set1_host /* #undef LWS_HAVE_RSA_SET0_KEY */ @@ -110,7 +106,7 @@ /* #undef LWS_WITH_CGI */ /* whether the Openssl is recent enough, and / or built with, ecdh */ -#define LWS_HAVE_OPENSSL_ECDH_H +/* #undef LWS_HAVE_OPENSSL_ECDH_H */ /* HTTP Proxy support */ /* #undef LWS_WITH_HTTP_PROXY */ @@ -157,9 +153,9 @@ /* OpenSSL various APIs */ -/* #undef LWS_HAVE_TLS_CLIENT_METHOD */ -#define LWS_HAVE_TLSV1_2_CLIENT_METHOD -#define LWS_HAVE_SSL_SET_INFO_CALLBACK +#define LWS_HAVE_TLS_CLIENT_METHOD +/* #undef LWS_HAVE_TLSV1_2_CLIENT_METHOD */ +/* #undef LWS_HAVE_SSL_SET_INFO_CALLBACK */ #define LWS_HAS_INTPTR_T diff --git a/thirdparty/lws/mbedtls_verify.diff b/thirdparty/lws/mbedtls_verify.diff new file mode 100644 index 0000000000..d320645d67 --- /dev/null +++ b/thirdparty/lws/mbedtls_verify.diff @@ -0,0 +1,74 @@ +diff --git a/thirdparty/lws/client/ssl-client.c b/thirdparty/lws/client/ssl-client.c +index 6626e0844..962c6e3cb 100644 +--- a/thirdparty/lws/client/ssl-client.c ++++ b/thirdparty/lws/client/ssl-client.c +@@ -176,11 +176,7 @@ lws_ssl_client_bio_create(struct lws *wsi) + #endif + #else + #if defined(LWS_WITH_MBEDTLS) +- if (wsi->vhost->x509_client_CA) +- SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, OpenSSL_client_verify_callback); +- else +- SSL_set_verify(wsi->ssl, SSL_VERIFY_NONE, OpenSSL_client_verify_callback); +- ++ SSL_set_verify(wsi->ssl, SSL_VERIFY_PEER, OpenSSL_client_verify_callback); + #else + #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + SSL_set_tlsext_host_name(wsi->ssl, hostname); +diff --git a/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c b/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c +index 63504919c..4e3d61109 100644 +--- a/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c ++++ b/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c +@@ -218,7 +218,7 @@ static int ssl_pm_reload_crt(SSL *ssl) + struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm; + + if (ssl->verify_mode == SSL_VERIFY_PEER) +- mode = MBEDTLS_SSL_VERIFY_REQUIRED; ++ mode = MBEDTLS_SSL_VERIFY_OPTIONAL; + else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT) + mode = MBEDTLS_SSL_VERIFY_OPTIONAL; + else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE) +@@ -712,11 +712,39 @@ long ssl_pm_get_verify_result(const SSL *ssl) + struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; + + ret = mbedtls_ssl_get_verify_result(&ssl_pm->ssl); +- if (ret) { +- SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_get_verify_result() return 0x%x", ret); ++ ++ if (!ret) ++ return X509_V_OK; ++ ++ if (ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED || ++ (ret & MBEDTLS_X509_BADCRL_NOT_TRUSTED)) ++ // Allows us to use LCCSCF_ALLOW_SELFSIGNED to skip verification ++ verify_result = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; ++ ++ else if (ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) ++ verify_result = X509_V_ERR_HOSTNAME_MISMATCH; ++ ++ else if ((ret & MBEDTLS_X509_BADCERT_BAD_KEY) || ++ (ret & MBEDTLS_X509_BADCRL_BAD_KEY)) ++ verify_result = X509_V_ERR_CA_KEY_TOO_SMALL; ++ ++ else if ((ret & MBEDTLS_X509_BADCERT_BAD_MD) || ++ (ret & MBEDTLS_X509_BADCRL_BAD_MD)) ++ verify_result = X509_V_ERR_CA_MD_TOO_WEAK; ++ ++ else if ((ret & MBEDTLS_X509_BADCERT_FUTURE) || ++ (ret & MBEDTLS_X509_BADCRL_FUTURE)) ++ verify_result = X509_V_ERR_CERT_NOT_YET_VALID; ++ ++ else if ((ret & MBEDTLS_X509_BADCERT_EXPIRED) || ++ (ret & MBEDTLS_X509_BADCRL_EXPIRED)) ++ verify_result = X509_V_ERR_CERT_HAS_EXPIRED; ++ ++ else + verify_result = X509_V_ERR_UNSPECIFIED; +- } else +- verify_result = X509_V_OK; ++ ++ SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, ++ "mbedtls_ssl_get_verify_result() return 0x%x", ret); + + return verify_result; + } diff --git a/thirdparty/lws/mbedtls_wrapper/include/internal/ssl_types.h b/thirdparty/lws/mbedtls_wrapper/include/internal/ssl_types.h index 45198bc978..2ca438c422 100644 --- a/thirdparty/lws/mbedtls_wrapper/include/internal/ssl_types.h +++ b/thirdparty/lws/mbedtls_wrapper/include/internal/ssl_types.h @@ -215,6 +215,7 @@ struct ssl_st int (*verify_callback) (int ok, X509_STORE_CTX *ctx); int rwstate; + int interrupted_remaining_write; long verify_result; diff --git a/thirdparty/lws/mbedtls_wrapper/include/platform/ssl_port.h b/thirdparty/lws/mbedtls_wrapper/include/platform/ssl_port.h index fd461e9819..eca68f20d1 100644 --- a/thirdparty/lws/mbedtls_wrapper/include/platform/ssl_port.h +++ b/thirdparty/lws/mbedtls_wrapper/include/platform/ssl_port.h @@ -25,11 +25,13 @@ */ #include "string.h" -#ifdef __APPLE__ +/* GODOT ADDITION */ +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) #include <stdlib.h> #else #include "malloc.h" #endif +/* END GODOT ADDITION */ void *ssl_mem_zalloc(size_t size); diff --git a/thirdparty/lws/mbedtls_wrapper/library/ssl_lib.c b/thirdparty/lws/mbedtls_wrapper/library/ssl_lib.c index 187fc9f005..d8fdd06fad 100644 --- a/thirdparty/lws/mbedtls_wrapper/library/ssl_lib.c +++ b/thirdparty/lws/mbedtls_wrapper/library/ssl_lib.c @@ -142,9 +142,9 @@ int SSL_get_error(const SSL *ssl, int ret_code) ret = SSL_ERROR_NONE; else if (ret_code < 0) { - if (SSL_want_read(ssl)) + if (ssl->err == SSL_ERROR_WANT_READ || SSL_want_read(ssl)) ret = SSL_ERROR_WANT_READ; - else if (SSL_want_write(ssl)) + else if (ssl->err == SSL_ERROR_WANT_WRITE || SSL_want_write(ssl)) ret = SSL_ERROR_WANT_WRITE; else ret = SSL_ERROR_SYSCALL; //unknown @@ -457,7 +457,7 @@ int SSL_read(SSL *ssl, void *buffer, int len) int SSL_write(SSL *ssl, const void *buffer, int len) { int ret; - int send_bytes; + int send_bytes, bytes; const unsigned char *pbuf; SSL_ASSERT1(ssl); @@ -470,25 +470,36 @@ int SSL_write(SSL *ssl, const void *buffer, int len) pbuf = (const unsigned char *)buffer; do { - int bytes; - if (send_bytes > SSL_SEND_DATA_MAX_LENGTH) bytes = SSL_SEND_DATA_MAX_LENGTH; else bytes = send_bytes; + if (ssl->interrupted_remaining_write) { + bytes = ssl->interrupted_remaining_write; + ssl->interrupted_remaining_write = 0; + } + ret = SSL_METHOD_CALL(send, ssl, pbuf, bytes); + //printf("%s: ssl_pm said %d for %d requested (cum %d)\n", __func__, ret, bytes, len -send_bytes); + /* the return is a NEGATIVE OpenSSL error code, or the length sent */ if (ret > 0) { pbuf += ret; send_bytes -= ret; - } - } while (ret > 0 && send_bytes); + } else + ssl->interrupted_remaining_write = bytes; + } while (ret > 0 && send_bytes && ret == bytes); if (ret >= 0) { ret = len - send_bytes; - ssl->rwstate = SSL_NOTHING; - } else - ret = -1; + if (!ret) + ssl->rwstate = SSL_NOTHING; + } else { + if (send_bytes == len) + ret = -1; + else + ret = len - send_bytes; + } return ret; } diff --git a/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c b/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c index 536733fbab..4e3d611095 100644 --- a/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c +++ b/thirdparty/lws/mbedtls_wrapper/platform/ssl_pm.c @@ -218,7 +218,7 @@ static int ssl_pm_reload_crt(SSL *ssl) struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm; if (ssl->verify_mode == SSL_VERIFY_PEER) - mode = MBEDTLS_SSL_VERIFY_REQUIRED; + mode = MBEDTLS_SSL_VERIFY_OPTIONAL; else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT) mode = MBEDTLS_SSL_VERIFY_OPTIONAL; else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE) @@ -360,17 +360,52 @@ int ssl_pm_read(SSL *ssl, void *buffer, int len) return ret; } +/* + * This returns -1, or the length sent. + * If -1, then you need to find out if the error was + * fatal or recoverable using SSL_get_error() + */ int ssl_pm_send(SSL *ssl, const void *buffer, int len) { int ret; struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len); + /* + * We can get a positive number, which may be less than len... that + * much was sent successfully and you can call again to send more. + * + * We can get a negative mbedtls error code... if WANT_WRITE or WANT_READ, + * it's nonfatal and means it should be retried as-is. If something else, + * it's fatal actually. + * + * If this function returns something other than a positive value or + * MBEDTLS_ERR_SSL_WANT_READ/WRITE, the ssl context becomes unusable, and + * you should either free it or call mbedtls_ssl_session_reset() on it + * before re-using it for a new connection; the current connection must + * be closed. + * + * When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, it must be + * called later with the same arguments, until it returns a positive value. + */ + if (ret < 0) { - if (ret == MBEDTLS_ERR_NET_CONN_RESET) + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_write() return -0x%x", -ret); + switch (ret) { + case MBEDTLS_ERR_NET_CONN_RESET: ssl->err = SSL_ERROR_SYSCALL; - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_write() return -0x%x", -ret); - ret = -1; + break; + case MBEDTLS_ERR_SSL_WANT_WRITE: + ssl->err = SSL_ERROR_WANT_WRITE; + break; + case MBEDTLS_ERR_SSL_WANT_READ: + ssl->err = SSL_ERROR_WANT_READ; + break; + default: + break; + } + + ret = -1; } return ret; @@ -677,11 +712,39 @@ long ssl_pm_get_verify_result(const SSL *ssl) struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; ret = mbedtls_ssl_get_verify_result(&ssl_pm->ssl); - if (ret) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_get_verify_result() return 0x%x", ret); + + if (!ret) + return X509_V_OK; + + if (ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED || + (ret & MBEDTLS_X509_BADCRL_NOT_TRUSTED)) + // Allows us to use LCCSCF_ALLOW_SELFSIGNED to skip verification + verify_result = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; + + else if (ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) + verify_result = X509_V_ERR_HOSTNAME_MISMATCH; + + else if ((ret & MBEDTLS_X509_BADCERT_BAD_KEY) || + (ret & MBEDTLS_X509_BADCRL_BAD_KEY)) + verify_result = X509_V_ERR_CA_KEY_TOO_SMALL; + + else if ((ret & MBEDTLS_X509_BADCERT_BAD_MD) || + (ret & MBEDTLS_X509_BADCRL_BAD_MD)) + verify_result = X509_V_ERR_CA_MD_TOO_WEAK; + + else if ((ret & MBEDTLS_X509_BADCERT_FUTURE) || + (ret & MBEDTLS_X509_BADCRL_FUTURE)) + verify_result = X509_V_ERR_CERT_NOT_YET_VALID; + + else if ((ret & MBEDTLS_X509_BADCERT_EXPIRED) || + (ret & MBEDTLS_X509_BADCRL_EXPIRED)) + verify_result = X509_V_ERR_CERT_HAS_EXPIRED; + + else verify_result = X509_V_ERR_UNSPECIFIED; - } else - verify_result = X509_V_OK; + + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, + "mbedtls_ssl_get_verify_result() return 0x%x", ret); return verify_result; } diff --git a/thirdparty/lws/minilex.c b/thirdparty/lws/minilex.c deleted file mode 100644 index 3cb1e33696..0000000000 --- a/thirdparty/lws/minilex.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * minilex.c - * - * High efficiency lexical state parser - * - * Copyright (C)2011-2014 Andy Green <andy@warmcat.com> - * - * Licensed under LGPL2 - * - * Usage: gcc minilex.c -o minilex && ./minilex > lextable.h - * - * Run it twice to test parsing on the generated table on stderr - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "lextable-strings.h" - -/* - * b7 = 0 = 1-byte seq - * 0x08 = fail - * 2-byte seq - * 0x00 - 0x07, then terminal as given in 2nd byte - 3-byte seq - * no match: go fwd 3 byte, match: jump fwd by amt in +1/+2 bytes - * = 1 = 1-byte seq - * no match: die, match go fwd 1 byte - */ - -unsigned char lextable[] = { - #include "lextable.h" -}; - -#define PARALLEL 30 - -struct state { - char c[PARALLEL]; - int state[PARALLEL]; - int count; - int bytepos; - - int real_pos; -}; - -struct state state[1000]; -int next = 1; - -#define FAIL_CHAR 0x08 - -int lextable_decode(int pos, char c) -{ - while (1) { - if (lextable[pos] & (1 << 7)) { /* 1-byte, fail on mismatch */ - if ((lextable[pos] & 0x7f) != c) - return -1; - /* fall thru */ - pos++; - if (lextable[pos] == FAIL_CHAR) - return -1; - return pos; - } else { /* b7 = 0, end or 3-byte */ - if (lextable[pos] < FAIL_CHAR) /* terminal marker */ - return pos; - - if (lextable[pos] == c) /* goto */ - return pos + (lextable[pos + 1]) + - (lextable[pos + 2] << 8); - /* fall thru goto */ - pos += 3; - /* continue */ - } - } -} - -int main(void) -{ - int n = 0; - int m = 0; - int prev; - char c; - int walk; - int saw; - int y; - int j; - int pos = 0; - - while (n < sizeof(set) / sizeof(set[0])) { - - m = 0; - walk = 0; - prev = 0; - - if (set[n][0] == '\0') { - n++; - continue; - } - - while (set[n][m]) { - - saw = 0; - for (y = 0; y < state[walk].count; y++) - if (state[walk].c[y] == set[n][m]) { - /* exists -- go forward */ - walk = state[walk].state[y]; - saw = 1; - break; - } - - if (saw) - goto again; - - /* something we didn't see before */ - - state[walk].c[state[walk].count] = set[n][m]; - - state[walk].state[state[walk].count] = next; - state[walk].count++; - walk = next++; -again: - m++; - } - - state[walk].c[0] = n++; - state[walk].state[0] = 0; /* terminal marker */ - state[walk].count = 1; - } - - walk = 0; - for (n = 0; n < next; n++) { - state[n].bytepos = walk; - walk += (2 * state[n].count); - } - - /* compute everyone's position first */ - - pos = 0; - walk = 0; - for (n = 0; n < next; n++) { - - state[n].real_pos = pos; - - for (m = 0; m < state[n].count; m++) { - - if (state[n].state[m] == 0) - pos += 2; /* terminal marker */ - else { /* c is a character */ - if ((state[state[n].state[m]].bytepos - - walk) == 2) - pos++; - else { - pos += 3; - if (m == state[n].count - 1) - pos++; /* fail */ - } - } - walk += 2; - } - } - - walk = 0; - pos = 0; - for (n = 0; n < next; n++) { - for (m = 0; m < state[n].count; m++) { - - if (!m) - fprintf(stdout, "/* pos %04x: %3d */ ", - state[n].real_pos, n); - else - fprintf(stdout, " "); - - y = state[n].c[m]; - saw = state[n].state[m]; - - if (saw == 0) { // c is a terminal then - - if (y > 0x7ff) { - fprintf(stderr, "terminal too big\n"); - return 2; - } - - fprintf(stdout, " 0x%02X, 0x%02X " - " " - "/* - terminal marker %2d - */,\n", - y >> 8, y & 0xff, y & 0x7f); - pos += 2; - walk += 2; - continue; - } - - /* c is a character */ - - prev = y &0x7f; - if (prev < 32 || prev > 126) - prev = '.'; - - - if ((state[saw].bytepos - walk) == 2) { - fprintf(stdout, " 0x%02X /* '%c' -> */,\n", - y | 0x80, prev); - pos++; - walk += 2; - continue; - } - - j = state[saw].real_pos - pos; - - if (j > 0xffff) { - fprintf(stderr, - "Jump > 64K bytes ahead (%d to %d)\n", - state[n].real_pos, state[saw].real_pos); - return 1; - } - fprintf(stdout, " 0x%02X /* '%c' */, 0x%02X, 0x%02X " - "/* (to 0x%04X state %3d) */,\n", - y, prev, - j & 0xff, j >> 8, - state[saw].real_pos, saw); - pos += 3; - - if (m == state[n].count - 1) { - fprintf(stdout, - " 0x%02X, /* fail */\n", - FAIL_CHAR); - pos++; /* fail */ - } - - walk += 2; - } - } - - fprintf(stdout, "/* total size %d bytes */\n", pos); - - /* - * Try to parse every legal input string - */ - - for (n = 0; n < sizeof(set) / sizeof(set[0]); n++) { - walk = 0; - m = 0; - y = -1; - - if (set[n][0] == '\0') - continue; - - fprintf(stderr, " trying '%s'\n", set[n]); - - while (set[n][m]) { - walk = lextable_decode(walk, set[n][m]); - if (walk < 0) { - fprintf(stderr, "failed\n"); - return 3; - } - - if (lextable[walk] < FAIL_CHAR) { - y = (lextable[walk] << 8) + lextable[walk + 1]; - break; - } - m++; - } - - if (y != n) { - fprintf(stderr, "decode failed %d\n", y); - return 4; - } - } - - fprintf(stderr, "All decode OK\n"); - - return 0; -} diff --git a/thirdparty/lws/misc/lejp.c b/thirdparty/lws/misc/lejp.c index 5407c90f97..38efa8b122 100644 --- a/thirdparty/lws/misc/lejp.c +++ b/thirdparty/lws/misc/lejp.c @@ -444,7 +444,7 @@ lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len) goto append_npos; } if (c == '.') { - if (ctx->dcount || (ctx->f & LEJP_SEEN_POINT)) { + if (!ctx->dcount || (ctx->f & LEJP_SEEN_POINT)) { ret = LEJP_REJECT_MP_VAL_NUM_FORMAT; goto reject; } diff --git a/thirdparty/lws/misc/sha-1.c b/thirdparty/lws/misc/sha-1.c index 9353fbefe4..50205a0100 100644 --- a/thirdparty/lws/misc/sha-1.c +++ b/thirdparty/lws/misc/sha-1.c @@ -45,7 +45,7 @@ struct sha1_ctxt { } h; union { unsigned char b8[8]; - u_int64_t b64[1]; + uint64_t b64[1]; } c; union { unsigned char b8[64]; diff --git a/thirdparty/lws/output.c b/thirdparty/lws/output.c index ed4752490e..375ff3ef99 100644 --- a/thirdparty/lws/output.c +++ b/thirdparty/lws/output.c @@ -270,9 +270,12 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len, if (wsi->state != LWSS_ESTABLISHED && ((wsi->state != LWSS_RETURNED_CLOSE_ALREADY && + wsi->state != LWSS_WAITING_TO_SEND_CLOSE_NOTIFICATION && wsi->state != LWSS_AWAITING_CLOSE_ACK) || - wp != LWS_WRITE_CLOSE)) + wp != LWS_WRITE_CLOSE)) { + lwsl_debug("binning\n"); return 0; + } /* if we are continuing a frame that already had its header done */ @@ -507,7 +510,7 @@ send_raw: (wp & 0x1f) == LWS_WRITE_HTTP_FINAL) && wsi->u.http.tx_content_length) { wsi->u.http.tx_content_remain -= len; - lwsl_info("%s: content_remain = %llu\n", __func__, + lwsl_info("%s: wsi %p: tx_content_remain = %llu\n", __func__, wsi, (unsigned long long)wsi->u.http.tx_content_remain); if (!wsi->u.http.tx_content_remain) { lwsl_info("%s: selecting final write mode\n", __func__); @@ -639,6 +642,9 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) poss = context->pt_serv_buf_size - n - LWS_H2_FRAME_HEADER_LENGTH; + if (poss > wsi->u.http.tx_content_remain) + poss = wsi->u.http.tx_content_remain; + /* * if there is a hint about how much we will do well to send at one time, * restrict ourselves to only trying to send that. diff --git a/thirdparty/lws/pollfd.c b/thirdparty/lws/pollfd.c index 4d6704d41c..54a4a86057 100644 --- a/thirdparty/lws/pollfd.c +++ b/thirdparty/lws/pollfd.c @@ -537,9 +537,14 @@ LWS_VISIBLE int lws_callback_on_writable_all_protocol(const struct lws_context *context, const struct lws_protocols *protocol) { - struct lws_vhost *vhost = context->vhost_list; + struct lws_vhost *vhost; int n; + if (!context) + return 0; + + vhost = context->vhost_list; + while (vhost) { for (n = 0; n < vhost->count_protocols; n++) if (protocol->callback == diff --git a/thirdparty/lws/private-libwebsockets.h b/thirdparty/lws/private-libwebsockets.h index 4f0b374332..535fa0be57 100644 --- a/thirdparty/lws/private-libwebsockets.h +++ b/thirdparty/lws/private-libwebsockets.h @@ -356,9 +356,6 @@ esp8266_tcp_stream_bind(lws_sockfd_type fd, int port, struct lws *wsi); #ifndef BYTE_ORDER #define BYTE_ORDER LITTLE_ENDIAN #endif -#ifndef u_int64_t -typedef unsigned __int64 u_int64_t; -#endif #undef __P #ifndef __P @@ -1633,7 +1630,6 @@ struct lws_h2_netconn { unsigned int pad_length:1; unsigned int collected_priority:1; unsigned int is_first_header_char:1; - unsigned int seen_nonpseudoheader:1; unsigned int zero_huff_padding:1; unsigned int last_action_dyntable_resize:1; @@ -1922,6 +1918,7 @@ struct lws { unsigned int hdr_parsing_completed:1; unsigned int http2_substream:1; unsigned int upgraded_to_http2:1; + unsigned int seen_nonpseudoheader:1; unsigned int listener:1; unsigned int user_space_externally_allocated:1; unsigned int socket_is_permanently_unusable:1; diff --git a/thirdparty/lws/server/ssl-server.c b/thirdparty/lws/server/ssl-server.c index a9516f2239..c4362824bf 100644 --- a/thirdparty/lws/server/ssl-server.c +++ b/thirdparty/lws/server/ssl-server.c @@ -155,7 +155,7 @@ lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg) */ vh = context->vhost_list; while (vh) { - if (!vh->being_destroyed && vh->ssl_ctx == SSL_get_SSL_CTX(ssl)) + if (!vh->being_destroyed && ssl && vh->ssl_ctx == SSL_get_SSL_CTX(ssl)) break; vh = vh->vhost_next; } diff --git a/thirdparty/lws/service.c b/thirdparty/lws/service.c index 6748e30bd4..8cf455e2c9 100644 --- a/thirdparty/lws/service.c +++ b/thirdparty/lws/service.c @@ -1073,6 +1073,8 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t c = lws_token_to_string(m); if (!c) break; + if (!(*c)) + break; len = lws_hdr_total_length(wsi, m); if (!len || len > sizeof(buf) - 1) { @@ -1090,6 +1092,11 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t m++; } while (1); + /* explicitly detach the ah */ + + lws_header_table_force_to_detachable_state(wsi); + lws_header_table_detach(wsi, 0); + /* ... and then drop the connection */ if (wsi->desc.sockfd == our_fd) @@ -1098,7 +1105,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS); - ah = ah->next; + ah = pt->ah_list; } #ifdef LWS_WITH_CGI @@ -1644,6 +1651,14 @@ drain: break; } #endif + /* + * something went wrong with parsing the handshake, and + * we ended up back in the event loop without completing it + */ + case LWSCM_PRE_WS_SERVING_ACCEPT: + wsi->socket_is_permanently_unusable = 1; + goto close_and_handled; + default: #ifdef LWS_NO_CLIENT break; diff --git a/thirdparty/lws/ssl.c b/thirdparty/lws/ssl.c index 0a647b469c..4ff3088ab3 100644 --- a/thirdparty/lws/ssl.c +++ b/thirdparty/lws/ssl.c @@ -20,11 +20,7 @@ */ #include "private-libwebsockets.h" - -/* workaround for mingw */ -#if !defined(ECONNABORTED) -#define ECONNABORTED 103 -#endif +#include <errno.h> int lws_alloc_vfs_file(struct lws_context *context, const char *filename, uint8_t **buf, lws_filepos_t *amount) @@ -463,7 +459,7 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len) lwsl_debug("%p: SSL_read says %d\n", wsi, n); /* manpage: returning 0 means connection shut down */ - if (!n) { + if (!n || (n == -1 && errno == ENOTCONN)) { wsi->socket_is_permanently_unusable = 1; return LWS_SSL_CAPABLE_ERROR; @@ -476,12 +472,12 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len) m == SSL_ERROR_SYSCALL) return LWS_SSL_CAPABLE_ERROR; - if (SSL_want_read(wsi->ssl)) { + if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->ssl)) { lwsl_debug("%s: WANT_READ\n", __func__); lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi); return LWS_SSL_CAPABLE_MORE_SERVICE; } - if (SSL_want_write(wsi->ssl)) { + if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->ssl)) { lwsl_debug("%s: WANT_WRITE\n", __func__); lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi); return LWS_SSL_CAPABLE_MORE_SERVICE; @@ -885,6 +881,7 @@ go_again: failed: lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_SSL_CONNECTIONS_FAILED, 1); + wsi->socket_is_permanently_unusable = 1; lwsl_info("SSL_accept failed socket %u: %s\n", wsi->desc.sockfd, lws_ssl_get_error_string(m, n, buf, sizeof(buf))); lws_ssl_elaborate_error(); @@ -903,7 +900,7 @@ accepted: /* adapt our vhost to match the SNI SSL_CTX that was chosen */ vh = context->vhost_list; while (vh) { - if (!vh->being_destroyed && + if (!vh->being_destroyed && wsi->ssl && vh->ssl_ctx == SSL_get_SSL_CTX(wsi->ssl)) { lwsl_info("setting wsi to vh %s\n", vh->name); wsi->vhost = vh; diff --git a/thirdparty/mbedtls/1453.diff b/thirdparty/mbedtls/1453.diff new file mode 100644 index 0000000000..acc3654cd4 --- /dev/null +++ b/thirdparty/mbedtls/1453.diff @@ -0,0 +1,120 @@ +diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c +index 67900c46c8..cefe882d2a 100644 +--- a/thirdparty/mbedtls/library/entropy_poll.c ++++ b/thirdparty/mbedtls/library/entropy_poll.c +@@ -54,28 +54,43 @@ + #define _WIN32_WINNT 0x0400 + #endif + #include <windows.h> +-#include <wincrypt.h> ++#include <bcrypt.h> ++#if defined(_MSC_VER) && _MSC_VER <= 1600 ++/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and ++ * <intsafe.h> are included, as they redefine a number of <TYPE>_MAX constants. ++ * These constants are guaranteed to be the same, though, so we suppress the ++ * warning when including intsafe.h. ++ */ ++#pragma warning( push ) ++#pragma warning( disable : 4005 ) ++#endif ++#include <intsafe.h> ++#if defined(_MSC_VER) && _MSC_VER <= 1600 ++#pragma warning( pop ) ++#endif + + int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len, + size_t *olen ) + { +- HCRYPTPROV provider; ++ ULONG len_as_ulong = 0; + ((void) data); + *olen = 0; + +- if( CryptAcquireContext( &provider, NULL, NULL, +- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) ++ /* ++ * BCryptGenRandom takes ULONG for size, which is smaller than size_t on ++ * 64-bit Windows platforms. Ensure len's value can be safely converted into ++ * a ULONG. ++ */ ++ if ( FAILED( SizeTToULong( len, &len_as_ulong ) ) ) + { + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } + +- if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) ++ if ( !BCRYPT_SUCCESS( BCryptGenRandom( NULL, output, len_as_ulong, BCRYPT_USE_SYSTEM_PREFERRED_RNG ) ) ) + { +- CryptReleaseContext( provider, 0 ); + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } + +- CryptReleaseContext( provider, 0 ); + *olen = len; + + return( 0 ); +diff --git a/thirdparty/mbedtls/library/x509_crt.c b/thirdparty/mbedtls/library/x509_crt.c +index afff4e18bf..7960fa1a1a 100644 +--- a/thirdparty/mbedtls/library/x509_crt.c ++++ b/thirdparty/mbedtls/library/x509_crt.c +@@ -64,6 +64,19 @@ + + #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + #include <windows.h> ++#if defined(_MSC_VER) && _MSC_VER <= 1600 ++/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and ++ * <intsafe.h> are included, as they redefine a number of <TYPE>_MAX constants. ++ * These constants are guaranteed to be the same, though, so we suppress the ++ * warning when including intsafe.h. ++ */ ++#pragma warning( push ) ++#pragma warning( disable : 4005 ) ++#endif ++#include <intsafe.h> ++#if defined(_MSC_VER) && _MSC_VER <= 1600 ++#pragma warning( pop ) ++#endif + #else + #include <time.h> + #endif +@@ -1130,6 +1143,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) + char filename[MAX_PATH]; + char *p; + size_t len = strlen( path ); ++ int lengthAsInt = 0; + + WIN32_FIND_DATAW file_data; + HANDLE hFind; +@@ -1144,7 +1158,18 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) + p = filename + len; + filename[len++] = '*'; + +- w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir, ++ if ( FAILED ( SizeTToInt( len, &lengthAsInt ) ) ) ++ return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); ++ ++ /* ++ * Note this function uses the code page CP_ACP, and assumes the incoming ++ * string is encoded in ANSI, before translating it into Unicode. If the ++ * incoming string were changed to be UTF-8, then the length check needs to ++ * change to check the number of characters, not the number of bytes, in the ++ * incoming string are less than MAX_PATH to avoid a buffer overrun with ++ * MultiByteToWideChar(). ++ */ ++ w_ret = MultiByteToWideChar( CP_ACP, 0, filename, lengthAsInt, szDir, + MAX_PATH - 3 ); + if( w_ret == 0 ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); +@@ -1161,8 +1186,11 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) + if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + continue; + ++ if ( FAILED( SizeTToInt( wcslen( file_data.cFileName ), &lengthAsInt ) ) ) ++ return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); ++ + w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, +- lstrlenW( file_data.cFileName ), ++ lengthAsInt, + p, (int) len - 1, + NULL, NULL ); + if( w_ret == 0 ) diff --git a/thirdparty/mbedtls/include/mbedtls/asn1.h b/thirdparty/mbedtls/include/mbedtls/asn1.h index fde328a128..96c1c9a8ab 100644 --- a/thirdparty/mbedtls/include/mbedtls/asn1.h +++ b/thirdparty/mbedtls/include/mbedtls/asn1.h @@ -88,6 +88,21 @@ #define MBEDTLS_ASN1_PRIMITIVE 0x00 #define MBEDTLS_ASN1_CONSTRUCTED 0x20 #define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80 + +/* + * Bit masks for each of the components of an ASN.1 tag as specified in + * ITU X.690 (08/2015), section 8.1 "General rules for encoding", + * paragraph 8.1.2.2: + * + * Bit 8 7 6 5 1 + * +-------+-----+------------+ + * | Class | P/C | Tag number | + * +-------+-----+------------+ + */ +#define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0 +#define MBEDTLS_ASN1_TAG_PC_MASK 0x20 +#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F + /* \} name */ /* \} addtogroup asn1_module */ diff --git a/thirdparty/mbedtls/include/mbedtls/ccm.h b/thirdparty/mbedtls/include/mbedtls/ccm.h index 5a9ee4a1cd..630b7fdf6c 100644 --- a/thirdparty/mbedtls/include/mbedtls/ccm.h +++ b/thirdparty/mbedtls/include/mbedtls/ccm.h @@ -105,7 +105,7 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * Must be at least \p length Bytes wide. * \param tag The buffer holding the tag. * \param tag_len The length of the tag to generate in Bytes: - * 4, 6, 8, 10, 14 or 16. + * 4, 6, 8, 10, 12, 14 or 16. * * \note The tag is written to a separate buffer. To concatenate * the \p tag with the \p output, as done in <em>RFC-3610: @@ -131,10 +131,13 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13. * \param add The additional data field. * \param add_len The length of additional data in Bytes. + * Must be less than 2^16 - 2^8. * \param input The buffer holding the input data. * \param output The buffer holding the output data. + * Must be at least \p length Bytes wide. * \param tag The buffer holding the tag. * \param tag_len The length of the tag in Bytes. + * 4, 6, 8, 10, 12, 14 or 16. * * \return 0 if successful and authenticated, or * #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. diff --git a/thirdparty/mbedtls/include/mbedtls/check_config.h b/thirdparty/mbedtls/include/mbedtls/check_config.h index 1143aa2687..be80332963 100644 --- a/thirdparty/mbedtls/include/mbedtls/check_config.h +++ b/thirdparty/mbedtls/include/mbedtls/check_config.h @@ -78,6 +78,10 @@ #error "MBEDTLS_DHM_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) && !defined(MBEDTLS_SSL_TRUNCATED_HMAC) +#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_CMAC_C) && \ !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) #error "MBEDTLS_CMAC_C defined, but not all prerequisites" diff --git a/thirdparty/mbedtls/include/mbedtls/config.h b/thirdparty/mbedtls/include/mbedtls/config.h index 79eedffddd..b5905ef9d0 100644 --- a/thirdparty/mbedtls/include/mbedtls/config.h +++ b/thirdparty/mbedtls/include/mbedtls/config.h @@ -1049,7 +1049,8 @@ /** * \def MBEDTLS_RSA_NO_CRT * - * Do not use the Chinese Remainder Theorem for the RSA private operation. + * Do not use the Chinese Remainder Theorem + * for the RSA private operation. * * Uncomment this macro to disable the use of CRT in RSA. * @@ -1412,6 +1413,30 @@ #define MBEDTLS_SSL_TRUNCATED_HMAC /** + * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT + * + * Fallback to old (pre-2.7), non-conforming implementation of the truncated + * HMAC extension which also truncates the HMAC key. Note that this option is + * only meant for a transitory upgrade period and is likely to be removed in + * a future version of the library. + * + * \warning The old implementation is non-compliant and has a security weakness + * (2^80 brute force attack on the HMAC key used for a single, + * uninterrupted connection). This should only be enabled temporarily + * when (1) the use of truncated HMAC is essential in order to save + * bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use + * the fixed implementation yet (pre-2.7). + * + * \deprecated This option is deprecated and will likely be removed in a + * future version of Mbed TLS. + * + * Uncomment to fallback to old, non-compliant truncated HMAC implementation. + * + * Requires: MBEDTLS_SSL_TRUNCATED_HMAC + */ +//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT + +/** * \def MBEDTLS_THREADING_ALT * * Provide your own alternate threading implementation. @@ -1517,6 +1542,9 @@ * * \note Currently compression can't be used with DTLS. * + * \deprecated This feature is deprecated and will be removed + * in the next major revision of the library. + * * Used in: library/ssl_tls.c * library/ssl_cli.c * library/ssl_srv.c diff --git a/thirdparty/mbedtls/include/mbedtls/dhm.h b/thirdparty/mbedtls/include/mbedtls/dhm.h index da2e66b111..00fafd8d16 100644 --- a/thirdparty/mbedtls/include/mbedtls/dhm.h +++ b/thirdparty/mbedtls/include/mbedtls/dhm.h @@ -372,7 +372,7 @@ MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_constant_t; * in <em>RFC-5114: Additional Diffie-Hellman Groups for Use with * IETF Standards</em>. */ -#define MBEDTLS_DHM_RFC5114_MODP_P \ +#define MBEDTLS_DHM_RFC5114_MODP_2048_P \ MBEDTLS_DEPRECATED_STRING_CONSTANT( \ "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" \ "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" \ diff --git a/thirdparty/mbedtls/include/mbedtls/md2.h b/thirdparty/mbedtls/include/mbedtls/md2.h index 2ff3f171a3..0fd8b5afcc 100644 --- a/thirdparty/mbedtls/include/mbedtls/md2.h +++ b/thirdparty/mbedtls/include/mbedtls/md2.h @@ -39,11 +39,6 @@ #define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED -0x002B /**< MD2 hardware accelerator failed */ -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - #if !defined(MBEDTLS_MD2_ALT) // Regular implementation // @@ -187,11 +182,7 @@ int mbedtls_internal_md2_process( mbedtls_md2_context *ctx ); * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md2_starts( - mbedtls_md2_context *ctx ) -{ - mbedtls_md2_starts_ret( ctx ); -} +MBEDTLS_DEPRECATED void mbedtls_md2_starts( mbedtls_md2_context *ctx ); /** * \brief MD2 process buffer @@ -207,13 +198,9 @@ MBEDTLS_DEPRECATED static inline void mbedtls_md2_starts( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md2_update( - mbedtls_md2_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_md2_update_ret( ctx, input, ilen ); -} +MBEDTLS_DEPRECATED void mbedtls_md2_update( mbedtls_md2_context *ctx, + const unsigned char *input, + size_t ilen ); /** * \brief MD2 final digest @@ -228,12 +215,8 @@ MBEDTLS_DEPRECATED static inline void mbedtls_md2_update( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md2_finish( - mbedtls_md2_context *ctx, - unsigned char output[16] ) -{ - mbedtls_md2_finish_ret( ctx, output ); -} +MBEDTLS_DEPRECATED void mbedtls_md2_finish( mbedtls_md2_context *ctx, + unsigned char output[16] ); /** * \brief MD2 process data block (internal use only) @@ -247,11 +230,7 @@ MBEDTLS_DEPRECATED static inline void mbedtls_md2_finish( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md2_process( - mbedtls_md2_context *ctx ) -{ - mbedtls_internal_md2_process( ctx ); -} +MBEDTLS_DEPRECATED void mbedtls_md2_process( mbedtls_md2_context *ctx ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ @@ -304,12 +283,9 @@ int mbedtls_md2_ret( const unsigned char *input, * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md2( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - mbedtls_md2_ret( input, ilen, output ); -} +MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input, + size_t ilen, + unsigned char output[16] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/thirdparty/mbedtls/include/mbedtls/md4.h b/thirdparty/mbedtls/include/mbedtls/md4.h index a2ab57f078..23fa95e46a 100644 --- a/thirdparty/mbedtls/include/mbedtls/md4.h +++ b/thirdparty/mbedtls/include/mbedtls/md4.h @@ -40,11 +40,6 @@ #define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED -0x002D /**< MD4 hardware accelerator failed */ -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - #if !defined(MBEDTLS_MD4_ALT) // Regular implementation // @@ -188,11 +183,7 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md4_starts( - mbedtls_md4_context *ctx ) -{ - mbedtls_md4_starts_ret( ctx ); -} +MBEDTLS_DEPRECATED void mbedtls_md4_starts( mbedtls_md4_context *ctx ); /** * \brief MD4 process buffer @@ -208,13 +199,9 @@ MBEDTLS_DEPRECATED static inline void mbedtls_md4_starts( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md4_update( - mbedtls_md4_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_md4_update_ret( ctx, input, ilen ); -} +MBEDTLS_DEPRECATED void mbedtls_md4_update( mbedtls_md4_context *ctx, + const unsigned char *input, + size_t ilen ); /** * \brief MD4 final digest @@ -229,12 +216,8 @@ MBEDTLS_DEPRECATED static inline void mbedtls_md4_update( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md4_finish( - mbedtls_md4_context *ctx, - unsigned char output[16] ) -{ - mbedtls_md4_finish_ret( ctx, output ); -} +MBEDTLS_DEPRECATED void mbedtls_md4_finish( mbedtls_md4_context *ctx, + unsigned char output[16] ); /** * \brief MD4 process data block (internal use only) @@ -249,12 +232,8 @@ MBEDTLS_DEPRECATED static inline void mbedtls_md4_finish( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md4_process( - mbedtls_md4_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_md4_process( ctx, data ); -} +MBEDTLS_DEPRECATED void mbedtls_md4_process( mbedtls_md4_context *ctx, + const unsigned char data[64] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ @@ -309,12 +288,9 @@ int mbedtls_md4_ret( const unsigned char *input, * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md4( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - mbedtls_md4_ret( input, ilen, output ); -} +MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input, + size_t ilen, + unsigned char output[16] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/thirdparty/mbedtls/include/mbedtls/md5.h b/thirdparty/mbedtls/include/mbedtls/md5.h index d49391f811..06ea4c5d44 100644 --- a/thirdparty/mbedtls/include/mbedtls/md5.h +++ b/thirdparty/mbedtls/include/mbedtls/md5.h @@ -43,11 +43,6 @@ // Regular implementation // -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - #ifdef __cplusplus extern "C" { #endif @@ -188,11 +183,7 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md5_starts( - mbedtls_md5_context *ctx ) -{ - mbedtls_md5_starts_ret( ctx ); -} +MBEDTLS_DEPRECATED void mbedtls_md5_starts( mbedtls_md5_context *ctx ); /** * \brief MD5 process buffer @@ -208,13 +199,9 @@ MBEDTLS_DEPRECATED static inline void mbedtls_md5_starts( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md5_update( - mbedtls_md5_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_md5_update_ret( ctx, input, ilen ); -} +MBEDTLS_DEPRECATED void mbedtls_md5_update( mbedtls_md5_context *ctx, + const unsigned char *input, + size_t ilen ); /** * \brief MD5 final digest @@ -229,12 +216,8 @@ MBEDTLS_DEPRECATED static inline void mbedtls_md5_update( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md5_finish( - mbedtls_md5_context *ctx, - unsigned char output[16] ) -{ - mbedtls_md5_finish_ret( ctx, output ); -} +MBEDTLS_DEPRECATED void mbedtls_md5_finish( mbedtls_md5_context *ctx, + unsigned char output[16] ); /** * \brief MD5 process data block (internal use only) @@ -249,12 +232,8 @@ MBEDTLS_DEPRECATED static inline void mbedtls_md5_finish( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md5_process( - mbedtls_md5_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_md5_process( ctx, data ); -} +MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx, + const unsigned char data[64] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ @@ -309,12 +288,9 @@ int mbedtls_md5_ret( const unsigned char *input, * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_md5( const unsigned char *input, - size_t ilen, - unsigned char output[16] ) -{ - mbedtls_md5_ret( input, ilen, output ); -} +MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input, + size_t ilen, + unsigned char output[16] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/thirdparty/mbedtls/include/mbedtls/oid.h b/thirdparty/mbedtls/include/mbedtls/oid.h index bf2ef5ece4..408645ece7 100644 --- a/thirdparty/mbedtls/include/mbedtls/oid.h +++ b/thirdparty/mbedtls/include/mbedtls/oid.h @@ -228,6 +228,14 @@ #define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */ +#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */ + +#define MBEDTLS_OID_HMAC_SHA256 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */ + +#define MBEDTLS_OID_HMAC_SHA384 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */ + +#define MBEDTLS_OID_HMAC_SHA512 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */ + /* * Encryption algorithms */ @@ -514,6 +522,16 @@ int mbedtls_oid_get_oid_by_sig_alg( mbedtls_pk_type_t pk_alg, mbedtls_md_type_t * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND */ int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg ); + +/** + * \brief Translate hmac algorithm OID into md_type + * + * \param oid OID to use + * \param md_hmac place to store message hmac algorithm + * + * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND + */ +int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac ); #endif /* MBEDTLS_MD_C */ /** diff --git a/thirdparty/mbedtls/include/mbedtls/ripemd160.h b/thirdparty/mbedtls/include/mbedtls/ripemd160.h index c21868b185..3a8b50a621 100644 --- a/thirdparty/mbedtls/include/mbedtls/ripemd160.h +++ b/thirdparty/mbedtls/include/mbedtls/ripemd160.h @@ -35,11 +35,6 @@ #define MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED -0x0031 /**< RIPEMD160 hardware accelerator failed */ -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - #if !defined(MBEDTLS_RIPEMD160_ALT) // Regular implementation // @@ -139,11 +134,8 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, * * \param ctx context to be initialized */ -MBEDTLS_DEPRECATED static inline void mbedtls_ripemd160_starts( - mbedtls_ripemd160_context *ctx ) -{ - mbedtls_ripemd160_starts_ret( ctx ); -} +MBEDTLS_DEPRECATED void mbedtls_ripemd160_starts( + mbedtls_ripemd160_context *ctx ); /** * \brief RIPEMD-160 process buffer @@ -154,13 +146,10 @@ MBEDTLS_DEPRECATED static inline void mbedtls_ripemd160_starts( * \param input buffer holding the data * \param ilen length of the input data */ -MBEDTLS_DEPRECATED static inline void mbedtls_ripemd160_update( +MBEDTLS_DEPRECATED void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx, const unsigned char *input, - size_t ilen ) -{ - mbedtls_ripemd160_update_ret( ctx, input, ilen ); -} + size_t ilen ); /** * \brief RIPEMD-160 final digest @@ -170,12 +159,9 @@ MBEDTLS_DEPRECATED static inline void mbedtls_ripemd160_update( * \param ctx RIPEMD-160 context * \param output RIPEMD-160 checksum result */ -MBEDTLS_DEPRECATED static inline void mbedtls_ripemd160_finish( +MBEDTLS_DEPRECATED void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, - unsigned char output[20] ) -{ - mbedtls_ripemd160_finish_ret( ctx, output ); -} + unsigned char output[20] ); /** * \brief RIPEMD-160 process data block (internal use only) @@ -185,12 +171,9 @@ MBEDTLS_DEPRECATED static inline void mbedtls_ripemd160_finish( * \param ctx RIPEMD-160 context * \param data buffer holding one block of data */ -MBEDTLS_DEPRECATED static inline void mbedtls_ripemd160_process( +MBEDTLS_DEPRECATED void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_ripemd160_process( ctx, data ); -} + const unsigned char data[64] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ @@ -235,13 +218,9 @@ int mbedtls_ripemd160_ret( const unsigned char *input, * \param ilen length of the input data * \param output RIPEMD-160 checksum result */ -MBEDTLS_DEPRECATED static inline void mbedtls_ripemd160( - const unsigned char *input, - size_t ilen, - unsigned char output[20] ) -{ - mbedtls_ripemd160_ret( input, ilen, output ); -} +MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input, + size_t ilen, + unsigned char output[20] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/thirdparty/mbedtls/include/mbedtls/rsa.h b/thirdparty/mbedtls/include/mbedtls/rsa.h index fb2f77f94f..5548f3c127 100644 --- a/thirdparty/mbedtls/include/mbedtls/rsa.h +++ b/thirdparty/mbedtls/include/mbedtls/rsa.h @@ -518,6 +518,18 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx, * * \note The input and output buffers must be large * enough. For example, 128 Bytes if RSA-1024 is used. + * + * \note Blinding is used if and only if a PRNG is provided. + * + * \note If blinding is used, both the base of exponentation + * and the exponent are blinded, providing protection + * against some side-channel attacks. + * + * \warning It is deprecated and a security risk to not provide + * a PRNG here and thereby prevent the use of blinding. + * Future versions of the library may enforce the presence + * of a PRNG. + * */ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), diff --git a/thirdparty/mbedtls/include/mbedtls/sha1.h b/thirdparty/mbedtls/include/mbedtls/sha1.h index e4f8650216..05540cde12 100644 --- a/thirdparty/mbedtls/include/mbedtls/sha1.h +++ b/thirdparty/mbedtls/include/mbedtls/sha1.h @@ -39,11 +39,6 @@ #define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED -0x0035 /**< SHA-1 hardware accelerator failed */ -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - #if !defined(MBEDTLS_SHA1_ALT) // Regular implementation // @@ -190,11 +185,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha1_starts( - mbedtls_sha1_context *ctx ) -{ - mbedtls_sha1_starts_ret( ctx ); -} +MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ); /** * \brief SHA-1 process buffer @@ -210,13 +201,9 @@ MBEDTLS_DEPRECATED static inline void mbedtls_sha1_starts( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha1_update( - mbedtls_sha1_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_sha1_update_ret( ctx, input, ilen ); -} +MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx, + const unsigned char *input, + size_t ilen ); /** * \brief SHA-1 final digest @@ -231,12 +218,8 @@ MBEDTLS_DEPRECATED static inline void mbedtls_sha1_update( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha1_finish( - mbedtls_sha1_context *ctx, - unsigned char output[20] ) -{ - mbedtls_sha1_finish_ret( ctx, output ); -} +MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, + unsigned char output[20] ); /** * \brief SHA-1 process data block (internal use only) @@ -251,12 +234,8 @@ MBEDTLS_DEPRECATED static inline void mbedtls_sha1_finish( * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha1_process( - mbedtls_sha1_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_sha1_process( ctx, data ); -} +MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx, + const unsigned char data[64] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ @@ -317,12 +296,9 @@ int mbedtls_sha1_ret( const unsigned char *input, * stronger message digests instead. * */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha1( const unsigned char *input, - size_t ilen, - unsigned char output[20] ) -{ - mbedtls_sha1_ret( input, ilen, output ); -} +MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input, + size_t ilen, + unsigned char output[20] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/thirdparty/mbedtls/include/mbedtls/sha256.h b/thirdparty/mbedtls/include/mbedtls/sha256.h index a2b6e11644..ffb16c277a 100644 --- a/thirdparty/mbedtls/include/mbedtls/sha256.h +++ b/thirdparty/mbedtls/include/mbedtls/sha256.h @@ -35,10 +35,6 @@ #define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED -0x0037 /**< SHA-256 hardware accelerator failed */ -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif #if !defined(MBEDTLS_SHA256_ALT) // Regular implementation // @@ -156,12 +152,8 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, * <ul><li>0: Use SHA-256.</li> * <li>1: Use SHA-224.</li></ul> */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha256_starts( - mbedtls_sha256_context *ctx, - int is224 ) -{ - mbedtls_sha256_starts_ret( ctx, is224 ); -} +MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, + int is224 ); /** * \brief This function feeds an input buffer into an ongoing @@ -173,13 +165,9 @@ MBEDTLS_DEPRECATED static inline void mbedtls_sha256_starts( * \param input The buffer holding the data. * \param ilen The length of the input data. */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha256_update( - mbedtls_sha256_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_sha256_update_ret( ctx, input, ilen ); -} +MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen ); /** * \brief This function finishes the SHA-256 operation, and writes @@ -190,12 +178,8 @@ MBEDTLS_DEPRECATED static inline void mbedtls_sha256_update( * \param ctx The SHA-256 context. * \param output The SHA-224or SHA-256 checksum result. */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha256_finish( - mbedtls_sha256_context *ctx, - unsigned char output[32] ) -{ - mbedtls_sha256_finish_ret( ctx, output ); -} +MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, + unsigned char output[32] ); /** * \brief This function processes a single data block within @@ -207,12 +191,8 @@ MBEDTLS_DEPRECATED static inline void mbedtls_sha256_finish( * \param ctx The SHA-256 context. * \param data The buffer holding one block of data. */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha256_process( - mbedtls_sha256_context *ctx, - const unsigned char data[64] ) -{ - mbedtls_internal_sha256_process( ctx, data ); -} +MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx, + const unsigned char data[64] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ @@ -276,14 +256,10 @@ int mbedtls_sha256_ret( const unsigned char *input, * <ul><li>0: Use SHA-256.</li> * <li>1: Use SHA-224.</li></ul> */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha256( - const unsigned char *input, - size_t ilen, - unsigned char output[32], - int is224 ) -{ - mbedtls_sha256_ret( input, ilen, output, is224 ); -} +MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input, + size_t ilen, + unsigned char output[32], + int is224 ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/thirdparty/mbedtls/include/mbedtls/sha512.h b/thirdparty/mbedtls/include/mbedtls/sha512.h index 52ae204d44..8404a2d599 100644 --- a/thirdparty/mbedtls/include/mbedtls/sha512.h +++ b/thirdparty/mbedtls/include/mbedtls/sha512.h @@ -35,10 +35,6 @@ #define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED -0x0039 /**< SHA-512 hardware accelerator failed */ -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif #if !defined(MBEDTLS_SHA512_ALT) // Regular implementation // @@ -156,12 +152,8 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, * <ul><li>0: Use SHA-512.</li> * <li>1: Use SHA-384.</li></ul> */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha512_starts( - mbedtls_sha512_context *ctx, - int is384 ) -{ - mbedtls_sha512_starts_ret( ctx, is384 ); -} +MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, + int is384 ); /** * \brief This function feeds an input buffer into an ongoing @@ -173,13 +165,9 @@ MBEDTLS_DEPRECATED static inline void mbedtls_sha512_starts( * \param input The buffer holding the data. * \param ilen The length of the input data. */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha512_update( - mbedtls_sha512_context *ctx, - const unsigned char *input, - size_t ilen ) -{ - mbedtls_sha512_update_ret( ctx, input, ilen ); -} +MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx, + const unsigned char *input, + size_t ilen ); /** * \brief This function finishes the SHA-512 operation, and writes @@ -190,12 +178,8 @@ MBEDTLS_DEPRECATED static inline void mbedtls_sha512_update( * \param ctx The SHA-512 context. * \param output The SHA-384 or SHA-512 checksum result. */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha512_finish( - mbedtls_sha512_context *ctx, - unsigned char output[64] ) -{ - mbedtls_sha512_finish_ret( ctx, output ); -} +MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, + unsigned char output[64] ); /** * \brief This function processes a single data block within @@ -207,12 +191,9 @@ MBEDTLS_DEPRECATED static inline void mbedtls_sha512_finish( * \param ctx The SHA-512 context. * \param data The buffer holding one block of data. */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha512_process( +MBEDTLS_DEPRECATED void mbedtls_sha512_process( mbedtls_sha512_context *ctx, - const unsigned char data[128] ) -{ - mbedtls_internal_sha512_process( ctx, data ); -} + const unsigned char data[128] ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ @@ -278,14 +259,10 @@ int mbedtls_sha512_ret( const unsigned char *input, * <ul><li>0: Use SHA-512.</li> * <li>1: Use SHA-384.</li></ul> */ -MBEDTLS_DEPRECATED static inline void mbedtls_sha512( - const unsigned char *input, - size_t ilen, - unsigned char output[64], - int is384 ) -{ - mbedtls_sha512_ret( input, ilen, output, is384 ); -} +MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input, + size_t ilen, + unsigned char output[64], + int is384 ); #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/thirdparty/mbedtls/include/mbedtls/ssl.h b/thirdparty/mbedtls/include/mbedtls/ssl.h index 51e843ae24..dffc162191 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl.h @@ -49,6 +49,15 @@ #endif #if defined(MBEDTLS_ZLIB_SUPPORT) + +#if defined(MBEDTLS_DEPRECATED_WARNING) +#warning "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and will be removed in the next major revision of the library" +#endif + +#if defined(MBEDTLS_DEPRECATED_REMOVED) +#error "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and cannot be used if MBEDTLS_DEPRECATED_REMOVED is set" +#endif + #include "zlib.h" #endif @@ -971,8 +980,13 @@ void mbedtls_ssl_init( mbedtls_ssl_context *ssl ); * \note No copy of the configuration context is made, it can be * shared by many mbedtls_ssl_context structures. * - * \warning Modifying the conf structure after it has been used in this - * function is unsupported! + * \warning The conf structure will be accessed during the session. + * It must not be modified or freed as long as the session + * is active. + * + * \warning This function must be called exactly once per context. + * Calling mbedtls_ssl_setup again is not supported, even + * if no session is active. * * \param ssl SSL context * \param conf SSL configuration to use diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h index 9f583a8777..60b431a0f4 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h @@ -71,6 +71,9 @@ #endif /* MBEDTLS_SSL_PROTO_TLS1 */ #endif /* MBEDTLS_SSL_PROTO_SSL3 */ +#define MBEDTLS_SSL_MIN_VALID_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 +#define MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 + /* Determine maximum supported version */ #define MBEDTLS_SSL_MAX_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h index 961be59c35..c3ee649f5c 100644 --- a/thirdparty/mbedtls/include/mbedtls/version.h +++ b/thirdparty/mbedtls/include/mbedtls/version.h @@ -39,7 +39,7 @@ * Major, Minor, Patchlevel */ #define MBEDTLS_VERSION_MAJOR 2 -#define MBEDTLS_VERSION_MINOR 7 +#define MBEDTLS_VERSION_MINOR 8 #define MBEDTLS_VERSION_PATCH 0 /** @@ -47,9 +47,9 @@ * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02070000 -#define MBEDTLS_VERSION_STRING "2.7.0" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.7.0" +#define MBEDTLS_VERSION_NUMBER 0x02080000 +#define MBEDTLS_VERSION_STRING "2.8.0" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.8.0" #if defined(MBEDTLS_VERSION_C) diff --git a/thirdparty/mbedtls/library/aes.c b/thirdparty/mbedtls/library/aes.c index dba4a5f578..3d2eac82dd 100644 --- a/thirdparty/mbedtls/library/aes.c +++ b/thirdparty/mbedtls/library/aes.c @@ -765,12 +765,14 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, } #endif /* !MBEDTLS_AES_ENCRYPT_ALT */ +#if !defined(MBEDTLS_DEPRECATED_REMOVED) void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ) { mbedtls_internal_aes_encrypt( ctx, input, output ); } +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ /* * AES-ECB block decryption @@ -831,12 +833,14 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, } #endif /* !MBEDTLS_AES_DECRYPT_ALT */ +#if !defined(MBEDTLS_DEPRECATED_REMOVED) void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ) { mbedtls_internal_aes_decrypt( ctx, input, output ); } +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ /* * AES-ECB block encryption/decryption diff --git a/thirdparty/mbedtls/library/bignum.c b/thirdparty/mbedtls/library/bignum.c index d27c130bcb..9f13da4421 100644 --- a/thirdparty/mbedtls/library/bignum.c +++ b/thirdparty/mbedtls/library/bignum.c @@ -1623,7 +1623,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos; int neg; - if( mbedtls_mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) + if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); if( mbedtls_mpi_cmp_int( E, 0 ) < 0 ) diff --git a/thirdparty/mbedtls/library/ctr_drbg.c b/thirdparty/mbedtls/library/ctr_drbg.c index c2310cb579..ff532a0134 100644 --- a/thirdparty/mbedtls/library/ctr_drbg.c +++ b/thirdparty/mbedtls/library/ctr_drbg.c @@ -19,7 +19,7 @@ * This file is part of mbed TLS (https://tls.mbed.org) */ /* - * The NIST SP 800-90 DRBGs are described in the following publucation. + * The NIST SP 800-90 DRBGs are described in the following publication. * * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf */ diff --git a/thirdparty/mbedtls/library/debug.c b/thirdparty/mbedtls/library/debug.c index f9229b3606..db3924ac54 100644 --- a/thirdparty/mbedtls/library/debug.c +++ b/thirdparty/mbedtls/library/debug.c @@ -91,7 +91,7 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, va_start( argp, format ); #if defined(_WIN32) -#if defined(_TRUNCATE) +#if defined(_TRUNCATE) && !defined(__MINGW32__) ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp ); #else ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c index 5e8a090b37..ed350735d0 100644 --- a/thirdparty/mbedtls/library/entropy_poll.c +++ b/thirdparty/mbedtls/library/entropy_poll.c @@ -55,16 +55,17 @@ #endif #include <windows.h> #include <bcrypt.h> -#if _MSC_VER <= 1600 -/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and <intsafe.h> are included, as they - * redefine a number of <TYPE>_MAX constants. These constants are guaranteed to be the same, though, so - * we suppress the warning when including intsafe.h. +#if defined(_MSC_VER) && _MSC_VER <= 1600 +/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and + * <intsafe.h> are included, as they redefine a number of <TYPE>_MAX constants. + * These constants are guaranteed to be the same, though, so we suppress the + * warning when including intsafe.h. */ #pragma warning( push ) #pragma warning( disable : 4005 ) #endif #include <intsafe.h> -#if _MSC_VER <= 1600 +#if defined(_MSC_VER) && _MSC_VER <= 1600 #pragma warning( pop ) #endif @@ -76,8 +77,9 @@ int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len *olen = 0; /* - * BCryptGenRandom takes ULONG for size, which is smaller than size_t on 64-bit platforms. - * Ensure len's value can be safely converted into a ULONG. + * BCryptGenRandom takes ULONG for size, which is smaller than size_t on + * 64-bit Windows platforms. Ensure len's value can be safely converted into + * a ULONG. */ if ( FAILED( SizeTToULong( len, &len_as_ulong ) ) ) { diff --git a/thirdparty/mbedtls/library/md2.c b/thirdparty/mbedtls/library/md2.c index 5028e8c586..b88aa406af 100644 --- a/thirdparty/mbedtls/library/md2.c +++ b/thirdparty/mbedtls/library/md2.c @@ -115,6 +115,13 @@ int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx ) return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md2_starts( mbedtls_md2_context *ctx ) +{ + mbedtls_md2_starts_ret( ctx ); +} +#endif + #if !defined(MBEDTLS_MD2_PROCESS_ALT) int mbedtls_internal_md2_process( mbedtls_md2_context *ctx ) { @@ -151,6 +158,13 @@ int mbedtls_internal_md2_process( mbedtls_md2_context *ctx ) return( 0 ); } + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md2_process( mbedtls_md2_context *ctx ) +{ + mbedtls_internal_md2_process( ctx ); +} +#endif #endif /* !MBEDTLS_MD2_PROCESS_ALT */ /* @@ -187,6 +201,15 @@ int mbedtls_md2_update_ret( mbedtls_md2_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md2_update( mbedtls_md2_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + mbedtls_md2_update_ret( ctx, input, ilen ); +} +#endif + /* * MD2 final digest */ @@ -214,6 +237,14 @@ int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md2_finish( mbedtls_md2_context *ctx, + unsigned char output[16] ) +{ + mbedtls_md2_finish_ret( ctx, output ); +} +#endif + #endif /* !MBEDTLS_MD2_ALT */ /* @@ -243,6 +274,15 @@ exit: return( ret ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md2( const unsigned char *input, + size_t ilen, + unsigned char output[16] ) +{ + mbedtls_md2_ret( input, ilen, output ); +} +#endif + #if defined(MBEDTLS_SELF_TEST) /* diff --git a/thirdparty/mbedtls/library/md4.c b/thirdparty/mbedtls/library/md4.c index 34a4b0e24e..ba704f58e8 100644 --- a/thirdparty/mbedtls/library/md4.c +++ b/thirdparty/mbedtls/library/md4.c @@ -111,6 +111,13 @@ int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx ) return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md4_starts( mbedtls_md4_context *ctx ) +{ + mbedtls_md4_starts_ret( ctx ); +} +#endif + #if !defined(MBEDTLS_MD4_PROCESS_ALT) int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64] ) @@ -217,6 +224,14 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, return( 0 ); } + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md4_process( mbedtls_md4_context *ctx, + const unsigned char data[64] ) +{ + mbedtls_internal_md4_process( ctx, data ); +} +#endif #endif /* !MBEDTLS_MD4_PROCESS_ALT */ /* @@ -273,6 +288,15 @@ int mbedtls_md4_update_ret( mbedtls_md4_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md4_update( mbedtls_md4_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + mbedtls_md4_update_ret( ctx, input, ilen ); +} +#endif + static const unsigned char md4_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -318,6 +342,14 @@ int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md4_finish( mbedtls_md4_context *ctx, + unsigned char output[16] ) +{ + mbedtls_md4_finish_ret( ctx, output ); +} +#endif + #endif /* !MBEDTLS_MD4_ALT */ /* @@ -347,6 +379,15 @@ exit: return( ret ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md4( const unsigned char *input, + size_t ilen, + unsigned char output[16] ) +{ + mbedtls_md4_ret( input, ilen, output ); +} +#endif + #if defined(MBEDTLS_SELF_TEST) /* diff --git a/thirdparty/mbedtls/library/md5.c b/thirdparty/mbedtls/library/md5.c index 8872dc467d..8440ebffcf 100644 --- a/thirdparty/mbedtls/library/md5.c +++ b/thirdparty/mbedtls/library/md5.c @@ -110,6 +110,13 @@ int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx ) return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md5_starts( mbedtls_md5_context *ctx ) +{ + mbedtls_md5_starts_ret( ctx ); +} +#endif + #if !defined(MBEDTLS_MD5_PROCESS_ALT) int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] ) @@ -236,6 +243,14 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, return( 0 ); } + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md5_process( mbedtls_md5_context *ctx, + const unsigned char data[64] ) +{ + mbedtls_internal_md5_process( ctx, data ); +} +#endif #endif /* !MBEDTLS_MD5_PROCESS_ALT */ /* @@ -289,6 +304,15 @@ int mbedtls_md5_update_ret( mbedtls_md5_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md5_update( mbedtls_md5_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + mbedtls_md5_update_ret( ctx, input, ilen ); +} +#endif + static const unsigned char md5_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -332,6 +356,14 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md5_finish( mbedtls_md5_context *ctx, + unsigned char output[16] ) +{ + mbedtls_md5_finish_ret( ctx, output ); +} +#endif + #endif /* !MBEDTLS_MD5_ALT */ /* @@ -361,6 +393,15 @@ exit: return( ret ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_md5( const unsigned char *input, + size_t ilen, + unsigned char output[16] ) +{ + mbedtls_md5_ret( input, ilen, output ); +} +#endif + #if defined(MBEDTLS_SELF_TEST) /* * RFC 1321 test vectors diff --git a/thirdparty/mbedtls/library/memory_buffer_alloc.c b/thirdparty/mbedtls/library/memory_buffer_alloc.c index 545d5a2c32..821ae2c708 100644 --- a/thirdparty/mbedtls/library/memory_buffer_alloc.c +++ b/thirdparty/mbedtls/library/memory_buffer_alloc.c @@ -113,7 +113,7 @@ static void debug_header( memory_header *hdr ) #endif } -static void debug_chain() +static void debug_chain( void ) { memory_header *cur = heap.first; @@ -180,11 +180,11 @@ static int verify_header( memory_header *hdr ) return( 0 ); } -static int verify_chain() +static int verify_chain( void ) { - memory_header *prv = heap.first, *cur = heap.first->next; + memory_header *prv = heap.first, *cur; - if( verify_header( heap.first ) != 0 ) + if( prv == NULL || verify_header( prv ) != 0 ) { #if defined(MBEDTLS_MEMORY_DEBUG) mbedtls_fprintf( stderr, "FATAL: verification of first header " @@ -202,6 +202,8 @@ static int verify_chain() return( 1 ); } + cur = heap.first->next; + while( cur != NULL ) { if( verify_header( cur ) != 0 ) @@ -245,7 +247,9 @@ static void *buffer_alloc_calloc( size_t n, size_t size ) original_len = len = n * size; - if( n != 0 && len / n != size ) + if( n == 0 || size == 0 || len / n != size ) + return( NULL ); + else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE ) return( NULL ); if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) @@ -386,7 +390,7 @@ static void buffer_alloc_free( void *ptr ) if( ptr == NULL || heap.buf == NULL || heap.first == NULL ) return; - if( p < heap.buf || p > heap.buf + heap.len ) + if( p < heap.buf || p >= heap.buf + heap.len ) { #if defined(MBEDTLS_MEMORY_DEBUG) mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed " @@ -500,13 +504,13 @@ void mbedtls_memory_buffer_set_verify( int verify ) heap.verify = verify; } -int mbedtls_memory_buffer_alloc_verify() +int mbedtls_memory_buffer_alloc_verify( void ) { return verify_chain(); } #if defined(MBEDTLS_MEMORY_DEBUG) -void mbedtls_memory_buffer_alloc_status() +void mbedtls_memory_buffer_alloc_status( void ) { mbedtls_fprintf( stderr, "Current use: %zu blocks / %zu bytes, max: %zu blocks / " @@ -570,8 +574,7 @@ static void buffer_alloc_free_mutexed( void *ptr ) void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ) { - memset( &heap, 0, sizeof(buffer_alloc_ctx) ); - memset( buf, 0, len ); + memset( &heap, 0, sizeof( buffer_alloc_ctx ) ); #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_init( &heap.mutex ); @@ -581,26 +584,30 @@ void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ) mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free ); #endif - if( (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) + if( len < sizeof( memory_header ) + MBEDTLS_MEMORY_ALIGN_MULTIPLE ) + return; + else if( (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) { /* Adjust len first since buf is used in the computation */ len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE - - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; + - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE - - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; + - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; } + memset( buf, 0, len ); + heap.buf = buf; heap.len = len; - heap.first = (memory_header *) buf; - heap.first->size = len - sizeof(memory_header); + heap.first = (memory_header *)buf; + heap.first->size = len - sizeof( memory_header ); heap.first->magic1 = MAGIC1; heap.first->magic2 = MAGIC2; heap.first_free = heap.first; } -void mbedtls_memory_buffer_alloc_free() +void mbedtls_memory_buffer_alloc_free( void ) { #if defined(MBEDTLS_THREADING_C) mbedtls_mutex_free( &heap.mutex ); @@ -620,7 +627,7 @@ static int check_pointer( void *p ) return( 0 ); } -static int check_all_free( ) +static int check_all_free( void ) { if( #if defined(MBEDTLS_MEMORY_DEBUG) diff --git a/thirdparty/mbedtls/library/net_sockets.c b/thirdparty/mbedtls/library/net_sockets.c index 754049005d..2fb548caa9 100644 --- a/thirdparty/mbedtls/library/net_sockets.c +++ b/thirdparty/mbedtls/library/net_sockets.c @@ -45,11 +45,14 @@ #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ !defined(EFI32) -#ifdef _WIN32_WINNT +/* GODOT ADDITION */ +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) #undef _WIN32_WINNT -#endif /* Enables getaddrinfo() & Co */ -#define _WIN32_WINNT 0x0601 +#define _WIN32_WINNT 0x0501 +#endif +/* END GODOT ADDITION */ + #include <ws2tcpip.h> #include <winsock2.h> diff --git a/thirdparty/mbedtls/library/oid.c b/thirdparty/mbedtls/library/oid.c index f13826ed74..edea950f8f 100644 --- a/thirdparty/mbedtls/library/oid.c +++ b/thirdparty/mbedtls/library/oid.c @@ -625,6 +625,51 @@ static const oid_md_alg_t oid_md_alg[] = FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg) FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg) FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg) + +/* + * For HMAC digestAlgorithm + */ +typedef struct { + mbedtls_oid_descriptor_t descriptor; + mbedtls_md_type_t md_hmac; +} oid_md_hmac_t; + +static const oid_md_hmac_t oid_md_hmac[] = +{ +#if defined(MBEDTLS_SHA1_C) + { + { ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ), "hmacSHA1", "HMAC-SHA-1" }, + MBEDTLS_MD_SHA1, + }, +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) + { + { ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ), "hmacSHA224", "HMAC-SHA-224" }, + MBEDTLS_MD_SHA224, + }, + { + { ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ), "hmacSHA256", "HMAC-SHA-256" }, + MBEDTLS_MD_SHA256, + }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { + { ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ), "hmacSHA384", "HMAC-SHA-384" }, + MBEDTLS_MD_SHA384, + }, + { + { ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ), "hmacSHA512", "HMAC-SHA-512" }, + MBEDTLS_MD_SHA512, + }, +#endif /* MBEDTLS_SHA512_C */ + { + { NULL, 0, NULL, NULL }, + MBEDTLS_MD_NONE, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_md_hmac_t, md_hmac, oid_md_hmac) +FN_OID_GET_ATTR1(mbedtls_oid_get_md_hmac, oid_md_hmac_t, md_hmac, mbedtls_md_type_t, md_hmac) #endif /* MBEDTLS_MD_C */ #if defined(MBEDTLS_PKCS12_C) diff --git a/thirdparty/mbedtls/library/pem.c b/thirdparty/mbedtls/library/pem.c index c09651f4a2..ac86d7e479 100644 --- a/thirdparty/mbedtls/library/pem.c +++ b/thirdparty/mbedtls/library/pem.c @@ -442,7 +442,7 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer, unsigned char *buf, size_t buf_len, size_t *olen ) { int ret; - unsigned char *encode_buf, *c, *p = buf; + unsigned char *encode_buf = NULL, *c, *p = buf; size_t len = 0, use_len, add_len = 0; mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len ); @@ -454,7 +454,8 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer, return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); } - if( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) + if( use_len != 0 && + ( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) ) return( MBEDTLS_ERR_PEM_ALLOC_FAILED ); if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data, diff --git a/thirdparty/mbedtls/library/pkcs5.c b/thirdparty/mbedtls/library/pkcs5.c index e28d5a8473..95f44fa98b 100644 --- a/thirdparty/mbedtls/library/pkcs5.c +++ b/thirdparty/mbedtls/library/pkcs5.c @@ -96,11 +96,9 @@ static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params, if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 ) return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); - if( MBEDTLS_OID_CMP( MBEDTLS_OID_HMAC_SHA1, &prf_alg_oid ) != 0 ) + if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 ) return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); - *md_type = MBEDTLS_MD_SHA1; - if( p != end ) return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); diff --git a/thirdparty/mbedtls/library/pkparse.c b/thirdparty/mbedtls/library/pkparse.c index b4def4f914..9022db2f93 100644 --- a/thirdparty/mbedtls/library/pkparse.c +++ b/thirdparty/mbedtls/library/pkparse.c @@ -181,6 +181,10 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end, { int ret; + if ( end - *p < 1 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + /* Tag may be either OID or SEQUENCE */ params->tag = **p; if( params->tag != MBEDTLS_ASN1_OID @@ -1277,6 +1281,9 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, { unsigned char *key_copy; + if( keylen == 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); + if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL ) return( MBEDTLS_ERR_PK_ALLOC_FAILED ); @@ -1348,11 +1355,45 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, { int ret; unsigned char *p; +#if defined(MBEDTLS_RSA_C) + const mbedtls_pk_info_t *pk_info; +#endif #if defined(MBEDTLS_PEM_PARSE_C) size_t len; mbedtls_pem_context pem; mbedtls_pem_init( &pem ); +#if defined(MBEDTLS_RSA_C) + /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ + if( keylen == 0 || key[keylen - 1] != '\0' ) + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + else + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN RSA PUBLIC KEY-----", + "-----END RSA PUBLIC KEY-----", + key, NULL, 0, &len ); + + if( ret == 0 ) + { + p = pem.buf; + if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) + return( ret ); + + if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 ) + mbedtls_pk_free( ctx ); + + mbedtls_pem_free( &pem ); + return( ret ); + } + else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + mbedtls_pem_free( &pem ); + return( ret ); + } +#endif /* MBEDTLS_RSA_C */ /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ if( keylen == 0 || key[keylen - 1] != '\0' ) @@ -1368,23 +1409,43 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, /* * Was PEM encoded */ - key = pem.buf; - keylen = pem.buflen; + p = pem.buf; + + ret = mbedtls_pk_parse_subpubkey( &p, p + pem.buflen, ctx ); + mbedtls_pem_free( &pem ); + return( ret ); } else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) { mbedtls_pem_free( &pem ); return( ret ); } + mbedtls_pem_free( &pem ); #endif /* MBEDTLS_PEM_PARSE_C */ + +#if defined(MBEDTLS_RSA_C) + if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 ) + return( ret ); + + p = (unsigned char *)key; + ret = pk_get_rsapubkey( &p, p + keylen, mbedtls_pk_rsa( *ctx ) ); + if( ret == 0 ) + { + return( ret ); + } + mbedtls_pk_free( ctx ); + if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) + { + return( ret ); + } +#endif /* MBEDTLS_RSA_C */ p = (unsigned char *) key; ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx ); -#if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_free( &pem ); -#endif - return( ret ); } diff --git a/thirdparty/mbedtls/library/platform.c b/thirdparty/mbedtls/library/platform.c index 76df7fac18..a295f9b9af 100644 --- a/thirdparty/mbedtls/library/platform.c +++ b/thirdparty/mbedtls/library/platform.c @@ -82,7 +82,7 @@ int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ) return( -1 ); va_start( argp, fmt ); -#if defined(_TRUNCATE) +#if defined(_TRUNCATE) && !defined(__MINGW32__) ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp ); #else ret = _vsnprintf( s, n, fmt, argp ); diff --git a/thirdparty/mbedtls/library/ripemd160.c b/thirdparty/mbedtls/library/ripemd160.c index b85b117c6a..2ba48b7fdb 100644 --- a/thirdparty/mbedtls/library/ripemd160.c +++ b/thirdparty/mbedtls/library/ripemd160.c @@ -112,6 +112,13 @@ int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx ) return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx ) +{ + mbedtls_ripemd160_starts_ret( ctx ); +} +#endif + #if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) /* * Process one block @@ -295,6 +302,14 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, return( 0 ); } + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, + const unsigned char data[64] ) +{ + mbedtls_internal_ripemd160_process( ctx, data ); +} +#endif #endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ /* @@ -349,6 +364,15 @@ int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + mbedtls_ripemd160_update_ret( ctx, input, ilen ); +} +#endif + static const unsigned char ripemd160_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -395,6 +419,14 @@ int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, + unsigned char output[20] ) +{ + mbedtls_ripemd160_finish_ret( ctx, output ); +} +#endif + #endif /* ! MBEDTLS_RIPEMD160_ALT */ /* @@ -424,6 +456,15 @@ exit: return( ret ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_ripemd160( const unsigned char *input, + size_t ilen, + unsigned char output[20] ) +{ + mbedtls_ripemd160_ret( input, ilen, output ); +} +#endif + #if defined(MBEDTLS_SELF_TEST) /* * Test vectors from the RIPEMD-160 paper and diff --git a/thirdparty/mbedtls/library/rsa.c b/thirdparty/mbedtls/library/rsa.c index 6526978e26..c9f7ba91b6 100644 --- a/thirdparty/mbedtls/library/rsa.c +++ b/thirdparty/mbedtls/library/rsa.c @@ -773,16 +773,38 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, { int ret; size_t olen; - mbedtls_mpi T, T1, T2; + + /* Temporary holding the result */ + mbedtls_mpi T; + + /* Temporaries holding P-1, Q-1 and the + * exponent blinding factor, respectively. */ mbedtls_mpi P1, Q1, R; -#if defined(MBEDTLS_RSA_NO_CRT) - mbedtls_mpi D_blind; - mbedtls_mpi *D = &ctx->D; -#else + +#if !defined(MBEDTLS_RSA_NO_CRT) + /* Temporaries holding the results mod p resp. mod q. */ + mbedtls_mpi TP, TQ; + + /* Temporaries holding the blinded exponents for + * the mod p resp. mod q computation (if used). */ mbedtls_mpi DP_blind, DQ_blind; + + /* Pointers to actual exponents to be used - either the unblinded + * or the blinded ones, depending on the presence of a PRNG. */ mbedtls_mpi *DP = &ctx->DP; mbedtls_mpi *DQ = &ctx->DQ; -#endif +#else + /* Temporary holding the blinded exponent (if used). */ + mbedtls_mpi D_blind; + + /* Pointer to actual exponent to be used - either the unblinded + * or the blinded one, depending on the presence of a PRNG. */ + mbedtls_mpi *D = &ctx->D; +#endif /* MBEDTLS_RSA_NO_CRT */ + + /* Temporaries holding the initial input and the double + * checked result; should be the same in the end. */ + mbedtls_mpi I, C; if( rsa_check_context( ctx, 1 /* private key checks */, f_rng != NULL /* blinding y/n */ ) != 0 ) @@ -790,8 +812,17 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); } - mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R ); +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + /* MPI Initialization */ + mbedtls_mpi_init( &T ); + + mbedtls_mpi_init( &P1 ); + mbedtls_mpi_init( &Q1 ); + mbedtls_mpi_init( &R ); if( f_rng != NULL ) { @@ -803,12 +834,15 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, #endif } - -#if defined(MBEDTLS_THREADING_C) - if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) - return( ret ); +#if !defined(MBEDTLS_RSA_NO_CRT) + mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ ); #endif + mbedtls_mpi_init( &I ); + mbedtls_mpi_init( &C ); + + /* End of MPI initialization */ + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) ); if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) { @@ -816,6 +850,8 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, goto cleanup; } + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) ); + if( f_rng != NULL ) { /* @@ -874,24 +910,25 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, /* * Faster decryption using the CRT * - * T1 = input ^ dP mod P - * T2 = input ^ dQ mod Q + * TP = input ^ dP mod P + * TQ = input ^ dQ mod Q */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, DP, &ctx->P, &ctx->RP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, DQ, &ctx->Q, &ctx->RQ ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TP, &T, DP, &ctx->P, &ctx->RP ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TQ, &T, DQ, &ctx->Q, &ctx->RQ ) ); /* - * T = (T1 - T2) * (Q^-1 mod P) mod P + * T = (TP - TQ) * (Q^-1 mod P) mod P */ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &TP, &TQ ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->QP ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &TP, &ctx->P ) ); /* - * T = T2 + T * Q + * T = TQ + T * Q */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->Q ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) ); #endif /* MBEDTLS_RSA_NO_CRT */ if( f_rng != NULL ) @@ -904,6 +941,15 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); } + /* Verify the result to prevent glitching attacks. */ + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E, + &ctx->N, &ctx->RN ) ); + if( mbedtls_mpi_cmp_mpi( &C, &I ) != 0 ) + { + ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; + goto cleanup; + } + olen = ctx->len; MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) ); @@ -913,8 +959,9 @@ cleanup: return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); #endif - mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); - mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &R ); + mbedtls_mpi_free( &P1 ); + mbedtls_mpi_free( &Q1 ); + mbedtls_mpi_free( &R ); if( f_rng != NULL ) { @@ -926,6 +973,15 @@ cleanup: #endif } + mbedtls_mpi_free( &T ); + +#if !defined(MBEDTLS_RSA_NO_CRT) + mbedtls_mpi_free( &TP ); mbedtls_mpi_free( &TQ ); +#endif + + mbedtls_mpi_free( &C ); + mbedtls_mpi_free( &I ); + if( ret != 0 ) return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret ); @@ -2222,7 +2278,8 @@ int mbedtls_rsa_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto cleanup; } if( verbose != 0 ) @@ -2237,7 +2294,8 @@ int mbedtls_rsa_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto cleanup; } if( verbose != 0 ) @@ -2250,7 +2308,8 @@ int mbedtls_rsa_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto cleanup; } if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) @@ -2258,7 +2317,8 @@ int mbedtls_rsa_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto cleanup; } if( verbose != 0 ) @@ -2283,7 +2343,8 @@ int mbedtls_rsa_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto cleanup; } if( verbose != 0 ) @@ -2296,7 +2357,8 @@ int mbedtls_rsa_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "failed\n" ); - return( 1 ); + ret = 1; + goto cleanup; } if( verbose != 0 ) diff --git a/thirdparty/mbedtls/library/sha1.c b/thirdparty/mbedtls/library/sha1.c index 8432eba8bd..1f29a0fbf8 100644 --- a/thirdparty/mbedtls/library/sha1.c +++ b/thirdparty/mbedtls/library/sha1.c @@ -111,6 +111,13 @@ int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ) return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) +{ + mbedtls_sha1_starts_ret( ctx ); +} +#endif + #if !defined(MBEDTLS_SHA1_PROCESS_ALT) int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) @@ -270,6 +277,14 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, return( 0 ); } + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha1_process( mbedtls_sha1_context *ctx, + const unsigned char data[64] ) +{ + mbedtls_internal_sha1_process( ctx, data ); +} +#endif #endif /* !MBEDTLS_SHA1_PROCESS_ALT */ /* @@ -322,6 +337,15 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha1_update( mbedtls_sha1_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + mbedtls_sha1_update_ret( ctx, input, ilen ); +} +#endif + static const unsigned char sha1_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -365,6 +389,14 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, + unsigned char output[20] ) +{ + mbedtls_sha1_finish_ret( ctx, output ); +} +#endif + #endif /* !MBEDTLS_SHA1_ALT */ /* @@ -394,6 +426,15 @@ exit: return( ret ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha1( const unsigned char *input, + size_t ilen, + unsigned char output[20] ) +{ + mbedtls_sha1_ret( input, ilen, output ); +} +#endif + #if defined(MBEDTLS_SELF_TEST) /* * FIPS-180-1 test vectors diff --git a/thirdparty/mbedtls/library/sha256.c b/thirdparty/mbedtls/library/sha256.c index abcd64d134..f39bcbab6c 100644 --- a/thirdparty/mbedtls/library/sha256.c +++ b/thirdparty/mbedtls/library/sha256.c @@ -135,6 +135,14 @@ int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ) return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, + int is224 ) +{ + mbedtls_sha256_starts_ret( ctx, is224 ); +} +#endif + #if !defined(MBEDTLS_SHA256_PROCESS_ALT) static const uint32_t K[] = { @@ -238,6 +246,14 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, return( 0 ); } + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha256_process( mbedtls_sha256_context *ctx, + const unsigned char data[64] ) +{ + mbedtls_internal_sha256_process( ctx, data ); +} +#endif #endif /* !MBEDTLS_SHA256_PROCESS_ALT */ /* @@ -290,6 +306,15 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha256_update( mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + mbedtls_sha256_update_ret( ctx, input, ilen ); +} +#endif + static const unsigned char sha256_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -339,6 +364,14 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, + unsigned char output[32] ) +{ + mbedtls_sha256_finish_ret( ctx, output ); +} +#endif + #endif /* !MBEDTLS_SHA256_ALT */ /* @@ -369,6 +402,16 @@ exit: return( ret ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha256( const unsigned char *input, + size_t ilen, + unsigned char output[32], + int is224 ) +{ + mbedtls_sha256_ret( input, ilen, output, is224 ); +} +#endif + #if defined(MBEDTLS_SELF_TEST) /* * FIPS-180-2 test vectors diff --git a/thirdparty/mbedtls/library/sha512.c b/thirdparty/mbedtls/library/sha512.c index c99b6da950..97cee07c56 100644 --- a/thirdparty/mbedtls/library/sha512.c +++ b/thirdparty/mbedtls/library/sha512.c @@ -149,6 +149,14 @@ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ) return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, + int is384 ) +{ + mbedtls_sha512_starts_ret( ctx, is384 ); +} +#endif + #if !defined(MBEDTLS_SHA512_PROCESS_ALT) /* @@ -269,6 +277,14 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, return( 0 ); } + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha512_process( mbedtls_sha512_context *ctx, + const unsigned char data[128] ) +{ + mbedtls_internal_sha512_process( ctx, data ); +} +#endif #endif /* !MBEDTLS_SHA512_PROCESS_ALT */ /* @@ -320,6 +336,15 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha512_update( mbedtls_sha512_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + mbedtls_sha512_update_ret( ctx, input, ilen ); +} +#endif + static const unsigned char sha512_padding[128] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -375,6 +400,14 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, return( 0 ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, + unsigned char output[64] ) +{ + mbedtls_sha512_finish_ret( ctx, output ); +} +#endif + #endif /* !MBEDTLS_SHA512_ALT */ /* @@ -405,6 +438,16 @@ exit: return( ret ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_sha512( const unsigned char *input, + size_t ilen, + unsigned char output[64], + int is384 ) +{ + mbedtls_sha512_ret( input, ilen, output, is384 ); +} +#endif + #if defined(MBEDTLS_SELF_TEST) /* diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c index 2534346a49..88864b8136 100644 --- a/thirdparty/mbedtls/library/ssl_cli.c +++ b/thirdparty/mbedtls/library/ssl_cli.c @@ -902,6 +902,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) *p++ = (unsigned char)( ciphersuites[i] ); } + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) ); + /* * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ @@ -909,6 +911,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) #endif { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) ); *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ); n++; @@ -928,8 +931,6 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) *q++ = (unsigned char)( n >> 7 ); *q++ = (unsigned char)( n << 1 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) ); - #if defined(MBEDTLS_ZLIB_SUPPORT) offer_compress = 1; #else @@ -2057,10 +2058,16 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, * * opaque psk_identity_hint<0..2^16-1>; */ + if( (*p) > end - 2 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message " + "(psk_identity_hint length)" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } len = (*p)[0] << 8 | (*p)[1]; *p += 2; - if( (*p) + len > end ) + if( (*p) > end - len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message " "(psk_identity_hint length)" ) ); @@ -2478,10 +2485,18 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) /* * Read signature */ + + if( p > end - 2 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } sig_len = ( p[0] << 8 ) | p[1]; p += 2; - if( end != p + sig_len ) + if( p != end - sig_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c index 617dedb1b0..236e52d767 100644 --- a/thirdparty/mbedtls/library/ssl_tls.c +++ b/thirdparty/mbedtls/library/ssl_tls.c @@ -501,6 +501,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) unsigned char *key2; unsigned char *mac_enc; unsigned char *mac_dec; + size_t mac_key_len; size_t iv_copy_len; const mbedtls_cipher_info_t *cipher_info; const mbedtls_md_info_t *md_info; @@ -692,6 +693,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) cipher_info->mode == MBEDTLS_MODE_CCM ) { transform->maclen = 0; + mac_key_len = 0; transform->ivlen = 12; transform->fixed_ivlen = 4; @@ -712,7 +714,8 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) } /* Get MAC length */ - transform->maclen = mbedtls_md_get_size( md_info ); + mac_key_len = mbedtls_md_get_size( md_info ); + transform->maclen = mac_key_len; #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) /* @@ -721,7 +724,16 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) * so we only need to adjust the length here. */ if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED ) + { transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN; + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) + /* Fall back to old, non-compliant version of the truncated + * HMAC implementation which also truncates the key + * (Mbed TLS versions from 1.3 to 2.6.0) */ + mac_key_len = transform->maclen; +#endif + } #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ /* IV length */ @@ -783,11 +795,11 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_CLI_C) if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) { - key1 = keyblk + transform->maclen * 2; - key2 = keyblk + transform->maclen * 2 + transform->keylen; + key1 = keyblk + mac_key_len * 2; + key2 = keyblk + mac_key_len * 2 + transform->keylen; mac_enc = keyblk; - mac_dec = keyblk + transform->maclen; + mac_dec = keyblk + mac_key_len; /* * This is not used in TLS v1.1. @@ -803,10 +815,10 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_SRV_C) if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) { - key1 = keyblk + transform->maclen * 2 + transform->keylen; - key2 = keyblk + transform->maclen * 2; + key1 = keyblk + mac_key_len * 2 + transform->keylen; + key2 = keyblk + mac_key_len * 2; - mac_enc = keyblk + transform->maclen; + mac_enc = keyblk + mac_key_len; mac_dec = keyblk; /* @@ -828,14 +840,14 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_PROTO_SSL3) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { - if( transform->maclen > sizeof transform->mac_enc ) + if( mac_key_len > sizeof transform->mac_enc ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - memcpy( transform->mac_enc, mac_enc, transform->maclen ); - memcpy( transform->mac_dec, mac_dec, transform->maclen ); + memcpy( transform->mac_enc, mac_enc, mac_key_len ); + memcpy( transform->mac_dec, mac_dec, mac_key_len ); } else #endif /* MBEDTLS_SSL_PROTO_SSL3 */ @@ -843,8 +855,8 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) defined(MBEDTLS_SSL_PROTO_TLS1_2) if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) { - mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, transform->maclen ); - mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, transform->maclen ); + mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len ); + mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len ); } else #endif @@ -864,7 +876,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) transform->iv_enc, transform->iv_dec, iv_copy_len, mac_enc, mac_dec, - transform->maclen ) ) != 0 ) + mac_key_len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret ); return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); @@ -877,7 +889,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) { ssl->conf->f_export_keys( ssl->conf->p_export_keys, session->master, keyblk, - transform->maclen, transform->keylen, + mac_key_len, transform->keylen, iv_copy_len ); } #endif @@ -7673,8 +7685,14 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, * Default */ default: - conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; - conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_1; /* TLS 1.0 */ + conf->min_major_ver = ( MBEDTLS_SSL_MIN_MAJOR_VERSION > + MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION ) ? + MBEDTLS_SSL_MIN_MAJOR_VERSION : + MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION; + conf->min_minor_ver = ( MBEDTLS_SSL_MIN_MINOR_VERSION > + MBEDTLS_SSL_MIN_VALID_MINOR_VERSION ) ? + MBEDTLS_SSL_MIN_MINOR_VERSION : + MBEDTLS_SSL_MIN_VALID_MINOR_VERSION; conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; diff --git a/thirdparty/mbedtls/library/version.c b/thirdparty/mbedtls/library/version.c index 6ca80d4695..fd96750885 100644 --- a/thirdparty/mbedtls/library/version.c +++ b/thirdparty/mbedtls/library/version.c @@ -30,7 +30,7 @@ #include "mbedtls/version.h" #include <string.h> -unsigned int mbedtls_version_get_number() +unsigned int mbedtls_version_get_number( void ) { return( MBEDTLS_VERSION_NUMBER ); } diff --git a/thirdparty/mbedtls/library/version_features.c b/thirdparty/mbedtls/library/version_features.c index 72afec2da0..da47e3d753 100644 --- a/thirdparty/mbedtls/library/version_features.c +++ b/thirdparty/mbedtls/library/version_features.c @@ -468,6 +468,9 @@ static const char *features[] = { #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) "MBEDTLS_SSL_TRUNCATED_HMAC", #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) + "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT", +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */ #if defined(MBEDTLS_THREADING_ALT) "MBEDTLS_THREADING_ALT", #endif /* MBEDTLS_THREADING_ALT */ diff --git a/thirdparty/mbedtls/library/x509_crl.c b/thirdparty/mbedtls/library/x509_crl.c index 55d12acd03..b0f39d428b 100644 --- a/thirdparty/mbedtls/library/x509_crl.c +++ b/thirdparty/mbedtls/library/x509_crl.c @@ -95,17 +95,23 @@ static int x509_crl_get_version( unsigned char **p, } /* - * X.509 CRL v2 extensions (no extensions parsed yet.) + * X.509 CRL v2 extensions + * + * We currently don't parse any extension's content, but we do check that the + * list of extensions is well-formed and abort on critical extensions (that + * are unsupported as we don't support any extension so far) */ static int x509_get_crl_ext( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *ext ) { int ret; - size_t len = 0; - /* Get explicit tag */ - if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0) ) != 0 ) + /* + * crlExtensions [0] EXPLICIT Extensions OPTIONAL + * -- if present, version MUST be v2 + */ + if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0 ) ) != 0 ) { if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) return( 0 ); @@ -115,11 +121,54 @@ static int x509_get_crl_ext( unsigned char **p, while( *p < end ) { + /* + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING } + */ + int is_critical = 0; + const unsigned char *end_ext_data; + size_t len; + + /* Get enclosing sequence tag */ if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + end_ext_data = *p + len; + + /* Get OID (currently ignored) */ + if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len, + MBEDTLS_ASN1_OID ) ) != 0 ) + { + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + } + *p += len; + + /* Get optional critical */ + if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, + &is_critical ) ) != 0 && + ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) + { + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + } + + /* Data should be octet string type */ + if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len, + MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + /* Ignore data so far and just check its length */ *p += len; + if( *p != end_ext_data ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + /* Abort on (unsupported) critical extensions */ + if( is_critical ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); } if( *p != end ) @@ -257,7 +306,7 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, { int ret; size_t len; - unsigned char *p, *end; + unsigned char *p = NULL, *end = NULL; mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; mbedtls_x509_crl *crl = chain; @@ -294,7 +343,11 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, /* * Copy raw DER-encoded CRL */ - if( ( p = mbedtls_calloc( 1, buflen ) ) == NULL ) + if( buflen == 0 ) + return( MBEDTLS_ERR_X509_INVALID_FORMAT ); + + p = mbedtls_calloc( 1, buflen ); + if( p == NULL ) return( MBEDTLS_ERR_X509_ALLOC_FAILED ); memcpy( p, buf, buflen ); diff --git a/thirdparty/mbedtls/library/x509_crt.c b/thirdparty/mbedtls/library/x509_crt.c index 6c592fdb5a..2a5dbb8783 100644 --- a/thirdparty/mbedtls/library/x509_crt.c +++ b/thirdparty/mbedtls/library/x509_crt.c @@ -62,16 +62,17 @@ #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) #include <windows.h> -#if _MSC_VER <= 1600 -/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and <intsafe.h> are included, as they - * redefine a number of <TYPE>_MAX constants. These constants are guaranteed to be the same, though, so - * we suppress the warning when including intsafe.h. +#if defined(_MSC_VER) && _MSC_VER <= 1600 +/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and + * <intsafe.h> are included, as they redefine a number of <TYPE>_MAX constants. + * These constants are guaranteed to be the same, though, so we suppress the + * warning when including intsafe.h. */ #pragma warning( push ) #pragma warning( disable : 4005 ) #endif #include <intsafe.h> -#if _MSC_VER <= 1600 +#if defined(_MSC_VER) && _MSC_VER <= 1600 #pragma warning( pop ) #endif #else @@ -145,7 +146,8 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), /* Only ECDSA */ - MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ), + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), #if defined(MBEDTLS_ECP_C) /* Only NIST P-256 and P-384 */ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | @@ -484,9 +486,12 @@ static int x509_get_subject_alt_name( unsigned char **p, if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 ) return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - if( ( tag & MBEDTLS_ASN1_CONTEXT_SPECIFIC ) != MBEDTLS_ASN1_CONTEXT_SPECIFIC ) + if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) != + MBEDTLS_ASN1_CONTEXT_SPECIFIC ) + { return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + } /* Skip everything but DNS name */ if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) ) @@ -1140,6 +1145,14 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) if ( FAILED ( SizeTToInt( len, &lengthAsInt ) ) ) return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); + /* + * Note this function uses the code page CP_ACP, and assumes the incoming + * string is encoded in ANSI, before translating it into Unicode. If the + * incoming string were changed to be UTF-8, then the length check needs to + * change to check the number of characters, not the number of bytes, in the + * incoming string are less than MAX_PATH to avoid a buffer overrun with + * MultiByteToWideChar(). + */ w_ret = MultiByteToWideChar( CP_ACP, 0, filename, lengthAsInt, szDir, MAX_PATH - 3 ); if( w_ret == 0 ) diff --git a/thirdparty/thekla_atlas/nvcore/Debug.h b/thirdparty/thekla_atlas/nvcore/Debug.h index f37a05c453..3804ed4763 100644 --- a/thirdparty/thekla_atlas/nvcore/Debug.h +++ b/thirdparty/thekla_atlas/nvcore/Debug.h @@ -200,10 +200,10 @@ namespace nv if (reinterpret_cast<uint64>(ptr) < 0x10000ULL) return false; if (reinterpret_cast<uint64>(ptr) >= 0x000007FFFFFEFFFFULL) return false; #else - if (reinterpret_cast<uint32>(ptr) == 0xcccccccc) return false; - if (reinterpret_cast<uint32>(ptr) == 0xcdcdcdcd) return false; - if (reinterpret_cast<uint32>(ptr) == 0xdddddddd) return false; - if (reinterpret_cast<uint32>(ptr) == 0xffffffff) return false; + if (reinterpret_cast<uintptr_t>(ptr) == 0xcccccccc) return false; + if (reinterpret_cast<uintptr_t>(ptr) == 0xcdcdcdcd) return false; + if (reinterpret_cast<uintptr_t>(ptr) == 0xdddddddd) return false; + if (reinterpret_cast<uintptr_t>(ptr) == 0xffffffff) return false; #endif return true; } diff --git a/thirdparty/thekla_atlas/poshlib/posh.h b/thirdparty/thekla_atlas/poshlib/posh.h index c3efe26a2d..3038297b39 100644 --- a/thirdparty/thekla_atlas/poshlib/posh.h +++ b/thirdparty/thekla_atlas/poshlib/posh.h @@ -498,6 +498,11 @@ Metrowerks: # define POSH_CPU_STRING "ARM" #endif +#if defined AARCH64 || defined __aarch64__ || defined _AARCH64 +# define POSH_CPU_STRONGARM 1 +# define POSH_CPU_STRING "AARCH64" +#endif + #if defined mips || defined __mips__ || defined __MIPS__ || defined _MIPS # define POSH_CPU_MIPS 1 # if defined _R5900 |