Compare commits

..

5 Commits

Author SHA1 Message Date
eb26ca7ae1 Merge pull request #101177 from akien-mga/1.1
[1.1] Build fixes for modern toolchains + new portable 1.1-stable Linux binaries
2025-11-21 11:32:06 +01:00
c47810c33b SCons: Ensure written files are properly flushed/closed
Also add `core/method_bind_ext.inc` to `.gitignore`.

(cherry picked from commit ad2fb7d93b)
2025-01-06 07:58:05 +01:00
8ee6e3848e OSX: Add support for building with osxcross
(cherry picked from commit eb111c1d39)
2025-01-06 07:57:56 +01:00
7ae44a055b Linux: Default to builtin openssl, freetype, and zlib
Fix support for cross-compilation, and fix handling of builtin libraries,
which would still attempt to link system libs and use system headers.

Also patch out GLU includes from GLEW, we don't need it, so that removes
another mandatory dependency.

(cherry picked from commit abf6a0919b)
2025-01-06 07:57:00 +01:00
a3a3cafbc8 SCons: Set explicit standards to C++98 and C11
Godot 1.0 was developed at a time where compilers defaulted to C++98.

Also disable `-Wall` on debug builds, there are now hundreds of warnings
from newer compilers that would need to be fixed.

This would best be done by adding a new `warnings` SCons option, which would
also affect non-debug builds, but I have no intention to fix warnings in the
1.0 branch, the goal here is just to get it to compile for archival and game
preservation.

(cherry picked from commit a68e96b8c2)
2025-01-06 07:45:24 +01:00
11802 changed files with 1475076 additions and 3182431 deletions

View File

@ -1,128 +0,0 @@
# Commented out parameters are those with the same value as base LLVM style
# We can uncomment them if we want to change their value, or enforce the
# chosen value in case the base style changes (last sync: Clang 6.0.1).
---
### General config, applies to all languages ###
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
# AlignConsecutiveAssignments: false
# AlignConsecutiveDeclarations: false
# AlignEscapedNewlines: Right
# AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
# AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: true
# AllowShortLoopsOnASingleLine: false
# AlwaysBreakAfterDefinitionReturnType: None
# AlwaysBreakAfterReturnType: None
# AlwaysBreakBeforeMultilineStrings: false
# AlwaysBreakTemplateDeclarations: false
# BinPackArguments: true
# BinPackParameters: true
# BraceWrapping:
# AfterClass: false
# AfterControlStatement: false
# AfterEnum: false
# AfterFunction: false
# AfterNamespace: false
# AfterObjCDeclaration: false
# AfterStruct: false
# AfterUnion: false
# AfterExternBlock: false
# BeforeCatch: false
# BeforeElse: false
# IndentBraces: false
# SplitEmptyFunction: true
# SplitEmptyRecord: true
# SplitEmptyNamespace: true
# BreakBeforeBinaryOperators: None
# BreakBeforeBraces: Attach
# BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: false
# BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: AfterColon
# BreakStringLiterals: true
ColumnLimit: 0
# CommentPragmas: '^ IWYU pragma:'
# CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
# DerivePointerAlignment: false
# DisableFormat: false
# ExperimentalAutoDetectBinPacking: false
# FixNamespaceComments: true
# ForEachMacros:
# - foreach
# - Q_FOREACH
# - BOOST_FOREACH
# IncludeBlocks: Preserve
IncludeCategories:
- Regex: '".*"'
Priority: 1
- Regex: '^<.*\.h>'
Priority: 2
- Regex: '^<.*'
Priority: 3
# IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true
# IndentPPDirectives: None
IndentWidth: 4
# IndentWrappedFunctionNames: false
# JavaScriptQuotes: Leave
# JavaScriptWrapImports: true
# KeepEmptyLinesAtTheStartOfBlocks: true
# MacroBlockBegin: ''
# MacroBlockEnd: ''
# MaxEmptyLinesToKeep: 1
# NamespaceIndentation: None
# PenaltyBreakAssignment: 2
# PenaltyBreakBeforeFirstCallParameter: 19
# PenaltyBreakComment: 300
# PenaltyBreakFirstLessLess: 120
# PenaltyBreakString: 1000
# PenaltyExcessCharacter: 1000000
# PenaltyReturnTypeOnItsOwnLine: 60
# PointerAlignment: Right
# RawStringFormats:
# - Delimiter: pb
# Language: TextProto
# BasedOnStyle: google
# ReflowComments: true
# SortIncludes: true
# SortUsingDeclarations: true
# SpaceAfterCStyleCast: false
# SpaceAfterTemplateKeyword: true
# SpaceBeforeAssignmentOperators: true
# SpaceBeforeParens: ControlStatements
# SpaceInEmptyParentheses: false
# SpacesBeforeTrailingComments: 1
# SpacesInAngles: false
# SpacesInContainerLiterals: true
# SpacesInCStyleCastParentheses: false
# SpacesInParentheses: false
# SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Always
---
### C++ specific config ###
Language: Cpp
Standard: Cpp03
---
### ObjC specific config ###
Language: ObjC
Standard: Cpp03
ObjCBlockIndentWidth: 4
# ObjCSpaceAfterProperty: false
# ObjCSpaceBeforeProtocolList: true
---
### Java specific config ###
Language: Java
# BreakAfterJavaFieldAnnotations: false
JavaImportGroups: ['org.godotengine', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax']
...

View File

@ -1,27 +0,0 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = tab
insert_final_newline = true
[*.{cpp,hpp,c,h,mm}]
trim_trailing_whitespace = true
[{*.gradle,AndroidManifest.xml}]
indent_style = space
indent_size = 4
[{*.{py,cs},SConstruct,SCsub}]
indent_style = space
indent_size = 4
# YAML requires indentation with spaces instead of tabs.
[*.{yml,yaml}]
indent_style = space
indent_size = 2
[*.{csproj,props,targets,nuspec}]
indent_style = space
indent_size = 2

15
.gitattributes vendored
View File

@ -1,15 +0,0 @@
# Properly detect languages on Github
*.h linguist-language=cpp
*.inc linguist-language=cpp
thirdparty/* linguist-vendored
# Normalize EOL for all files that Git considers text files
* text=auto eol=lf
# The above only works properly for Git 2.10+, so for older versions
# we need to manually list the binary files we don't want modified.
*.icns binary
*.ico binary
*.jar binary
*.png binary
*.ttf binary

174
.github/CODEOWNERS vendored
View File

@ -1,174 +0,0 @@
# Lines starting with '#' are comments.
# Each line is a file pattern followed by one or more owners.
# Owners can be @users, @org/teams or emails
# Buildsystem
.* @godotengine/buildsystem
.github/ @godotengine/buildsystem
*.py @godotengine/buildsystem
SConstruct @godotengine/buildsystem
SCsub @godotengine/buildsystem
# Core
/core/ @godotengine/core
/core/crypto/ @godotengine/network
/core/input*.* @godotengine/input
# Doc
/doc/ @godotengine/documentation
doc_classes/* @godotengine/documentation
# Drivers
## Audio
/drivers/alsa/ @godotengine/audio
/drivers/alsamidi/ @godotengine/audio
/drivers/coreaudio/ @godotengine/audio
/drivers/coremidi/ @godotengine/audio
/drivers/pulseaudio/ @godotengine/audio
/drivers/wasapi/ @godotengine/audio
/drivers/winmidi/ @godotengine/audio
/drivers/xaudio2/ @godotengine/audio
## Rendering
/drivers/dummy/ @godotengine/rendering
/drivers/gl_context/ @godotengine/rendering
/drivers/gles2/ @godotengine/rendering
/drivers/gles3/ @godotengine/rendering
/drivers/gles_common/ @godotengine/rendering
## OS
/drivers/unix/ @godotengine/_platforms
/drivers/windows/ @godotengine/windows
## Misc
/drivers/png/ @godotengine/import
# Editor
/editor/*debugger* @godotengine/debugger
/editor/icons/ @godotengine/usability
/editor/import/ @godotengine/import
/editor/plugins/*2d_*.* @godotengine/2d-editor
/editor/plugins/script_*.* @godotengine/script-editor
/editor/plugins/*shader*.* @godotengine/shaders
/editor/code_editor.* @godotengine/script-editor
/editor/*dock*.* @godotengine/docks
# Main
/main/ @godotengine/core
/main/tests/ @godotengine/tests
# Misc
/misc/ @godotengine/buildsystem
# Modules
## Audio (+ video)
/modules/minimp3/ @godotengine/audio
/modules/ogg/ @godotengine/audio
/modules/opus/ @godotengine/audio
/modules/stb_vorbis/ @godotengine/audio
/modules/theora/ @godotengine/audio
/modules/vorbis/ @godotengine/audio
/modules/webm/ @godotengine/audio
## Import
/modules/basis_universal/ @godotengine/import
/modules/bmp/ @godotengine/import
/modules/cvtt/ @godotengine/import
/modules/dds/ @godotengine/import
/modules/etc/ @godotengine/import
/modules/fbx/ @godotengine/import
/modules/gltf/ @godotengine/import
/modules/hdr/ @godotengine/import
/modules/jpg/ @godotengine/import
/modules/pvr/ @godotengine/import
/modules/squish/ @godotengine/import
/modules/svg/ @godotengine/import
/modules/tga/ @godotengine/import
/modules/tinyexr/ @godotengine/import
/modules/webp/ @godotengine/import
## Network
/modules/enet/ @godotengine/network
/modules/mbedtls/ @godotengine/network
/modules/upnp/ @godotengine/network
/modules/webrtc/ @godotengine/network
/modules/websocket/ @godotengine/network
## Rendering
/modules/denoise/ @godotengine/rendering
/modules/glslang/ @godotengine/rendering
/modules/lightmapper_cpu/ @godotengine/rendering
/modules/meshoptimizer/ @godotengine/rendering
/modules/raycast/ @godotengine/rendering
/modules/vhacd/ @godotengine/rendering
/modules/xatlas_unwrap/ @godotengine/rendering
## Scripting
/modules/gdnative/ @godotengine/gdnative
/modules/gdscript/ @godotengine/gdscript
/modules/jsonrpc/ @godotengine/gdscript
/modules/mono/ @godotengine/mono
/modules/visual_script/ @godotengine/visualscript
## Text
/modules/freetype/ @godotengine/buildsystem
/modules/gdnative/text/ @godotengine/gui-nodes
/modules/text_server_adv/ @godotengine/gui-nodes
/modules/text_server_fb/ @godotengine/gui-nodes
## XR
/modules/camera/ @godotengine/xr
/modules/gdnative/arvr/ @godotengine/xr
/modules/mobile_vr/ @godotengine/xr
/modules/webxr/ @godotengine/xr
## Misc
/modules/bullet/ @godotengine/physics
/modules/csg/ @godotengine/3d-nodes
/modules/gridmap/ @godotengine/3d-nodes
/modules/opensimplex/ @godotengine/3d-nodes
/modules/recast/ @godotengine/navigation
/modules/regex/ @godotengine/core
# Platform
/platform/android/ @godotengine/android
/platform/iphone/ @godotengine/ios
/platform/javascript/ @godotengine/html5
/platform/x11/ @godotengine/linux-bsd
/platform/osx/ @godotengine/macos
/platform/uwp/ @godotengine/uwp
/platform/windows/ @godotengine/windows
# Scene
/scene/2d/ @godotengine/2d-nodes
/scene/3d/ @godotengine/3d-nodes
/scene/animation/ @godotengine/animation
/scene/audio/ @godotengine/audio
/scene/debugger/ @godotengine/debugger
/scene/gui/ @godotengine/gui-nodes
/scene/main/ @godotengine/core
/scene/resources/default_theme/ @godotengine/gui-nodes
/scene/resources/font.* @godotengine/gui-nodes
/scene/resources/visual_shader*.* @godotengine/shaders
# Servers
/servers/arvr* @godotengine/xr
/servers/audio* @godotengine/audio
/servers/camera* @godotengine/xr
/servers/physics* @godotengine/physics
/servers/visual* @godotengine/rendering
# Thirdparty
/thirdparty/ @godotengine/buildsystem

View File

@ -1,18 +0,0 @@
---
name: Bug report
about: Report a bug in Godot
title: ''
labels: ''
assignees: ''
---
**Godot version:**
**OS/device including version:**
**Issue description:**
**Steps to reproduce:**
**Minimal reproduction project:**

View File

@ -1,19 +0,0 @@
---
name: Feature / Enhancement Request
about: Adding new features or improving existing ones.
title: 'IMPORTANT: This repository no longer accepts feature / enhancement requests.'
labels: ''
assignees: ''
---
**IMPORTANT, PLEASE READ**
Feature / Enhancement requests are no longer accepted in the main Godot repository.
Please open an item by filling the relevant fields in the *Proposals* repository:
https://github.com/godotengine/godot-proposals/issues/new/choose
Do not submit to this repository or your issue will be closed.
**IMPORTANT, PLEASE READ**

View File

@ -1,75 +0,0 @@
name: 🤖 Android Builds
on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=android verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
jobs:
android-template:
runs-on: "ubuntu-20.04"
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
- name: Set up Java 8
uses: actions/setup-java@v1
with:
java-version: 8
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: android-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons target=release tools=no android_arch=armv7
scons target=release tools=no android_arch=arm64v8
cd platform/android/java
./gradlew generateGodotTemplates
cd ../../..
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14

View File

@ -1,59 +0,0 @@
name: 🍏 iOS Builds
on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=iphone verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
jobs:
ios-template:
runs-on: "macos-latest"
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: ios-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons target=release tools=no
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14

View File

@ -1,86 +0,0 @@
name: 🌐 JavaScript Builds
on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=javascript verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
EM_VERSION: 2.0.15
EM_CACHE_FOLDER: 'emsdk-cache'
jobs:
javascript-template:
runs-on: "ubuntu-20.04"
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: javascript-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Additional cache for Emscripten generated system libraries
- name: Load Emscripten cache
id: javascript-template-emscripten-cache
uses: actions/cache@v2
with:
path: ${{env.EM_CACHE_FOLDER}}
key: ${{env.EM_VERSION}}-${{github.job}}
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Set up Emscripten latest
uses: mymindstorm/setup-emsdk@v10
with:
version: ${{env.EM_VERSION}}
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
- name: Verify Emscripten setup
run: |
emcc -v
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons target=release tools=no use_closure_compiler=yes
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14

View File

@ -1,225 +0,0 @@
name: 🐧 Linux Builds
on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=linuxbsd verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
jobs:
linux-editor-mono:
runs-on: "ubuntu-20.04"
name: Editor w/ Mono (target=release_debug, tools=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev xvfb \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: linux-editor-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Use python 3.x release (works cross platform; best to keep self contained in it's own step)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
# We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons tools=yes target=release_debug module_mono_enabled=yes mono_glue=no
xvfb-run ./bin/godot.x11.opt.tools.64.mono --generate-mono-glue modules/mono/glue || true
scons tools=yes target=release_debug module_mono_enabled=yes mono_glue=yes
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14
linux-template-mono:
runs-on: "ubuntu-20.04"
name: Template w/ Mono (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: linux-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons target=release tools=no module_mono_enabled=yes mono_glue=no
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14
linux-editor-sanitizers:
runs-on: "ubuntu-20.04"
name: Editor and exported project with sanitizers (target=debug/release, tools=yes/no, use_ubsan=yes, use_asan=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm \
xvfb wget2 unzip
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: linux-sanitizer-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Use python 3.x release (works cross platform; best to keep self contained in it's own step)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
# We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons tools=yes target=debug use_asan=yes use_ubsan=yes
ls -l bin/
# Download test project
# CI has no audio device, so use the Dummy audio driver to avoid spurious error messages.
- name: Download project
run: |
wget2 https://github.com/qarmin/RegressionTestProject/archive/3.3.zip
unzip 3.3.zip
mv "RegressionTestProject-3.3" "test_project"
# Editor is quite complicated piece of software, so it is easy to introduce bug here
- name: Open and close editor
run: |
DRI_PRIME=0 xvfb-run bin/godot.x11.tools.64s --audio-driver Dummy -e -q --path test_project 2>&1 | tee sanitizers_log.txt || true
misc/scripts/check_ci_log.py sanitizers_log.txt
# Run test project
- name: Run project
run: |
DRI_PRIME=0 xvfb-run bin/godot.x11.tools.64s 30 --video-driver GLES3 --audio-driver Dummy --path test_project 2>&1 | tee sanitizers_log.txt || true
misc/scripts/check_ci_log.py sanitizers_log.txt
# Check class reference
- name: Check for class reference updates
run: |
echo "Running --doctool to see if this changes the public API without updating the documentation."
echo -e "If a diff is shown, it means that your code/doc changes are incomplete and you should update the class reference with --doctool.\n\n"
DRI_PRIME=0 xvfb-run bin/godot.x11.tools.64s --doctool . 2>&1 > /dev/null || true
git diff --color --exit-code

View File

@ -1,111 +0,0 @@
name: 🍎 macOS Builds
on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=osx verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
jobs:
macos-editor:
runs-on: "macos-latest"
name: Editor (target=release_debug, tools=yes)
steps:
- uses: actions/checkout@v2
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: macos-editor-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Use python 3.x release (works cross platform; best to keep self contained in it's own step)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
# We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons tools=yes target=release_debug
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14
macos-template:
runs-on: "macos-latest"
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: macos-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons target=release tools=no
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14

View File

@ -1,120 +0,0 @@
name: ☁ Server Builds
on: [push, pull_request]
# Global Cache Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=server verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
jobs:
linux-editor:
runs-on: "ubuntu-20.04"
name: Linux Headless w/ Mono (target=release_debug, tools=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: linux-headless-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Use python 3.x release (works cross platform; best to keep self contained in it's own step)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
# We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons -j2 verbose=yes warnings=all werror=yes platform=server tools=yes target=release_debug module_mono_enabled=yes mono_glue=no
linux-server:
runs-on: "ubuntu-20.04"
name: Linux Server w/ Mono (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: linux-server-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons -j2 target=release tools=no module_mono_enabled=yes mono_glue=no

View File

@ -1,47 +0,0 @@
name: 📊 Static Checks
on: [push, pull_request]
jobs:
static-checks:
name: Static Checks (clang-format, black format, file format, documentation checks)
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent Azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
- name: Install dependencies
run: |
sudo apt-get install -qq dos2unix recode clang-format-11
sudo update-alternatives --remove-all clang-format
sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-11 100
sudo pip3 install black==20.8b1 pygments
- name: File formatting checks (file_format.sh)
run: |
bash ./misc/scripts/file_format.sh
- name: Style checks via clang-format (clang_format.sh)
run: |
bash ./misc/scripts/clang_format.sh
- name: Python style checks via black (black_format.sh)
run: |
bash ./misc/scripts/black_format.sh
- name: JavaScript style and documentation checks via ESLint and JSDoc
run: |
cd platform/javascript
npm ci
npm run lint
npm run docs -- -d dry-run
- name: Documentation checks
run: |
doc/tools/makerst.py --dry-run doc/classes modules

View File

@ -1,117 +0,0 @@
name: 🏁 Windows Builds
on: [push, pull_request]
# Global Settings
# SCONS_CACHE for windows must be set in the build environment
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=windows verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_MSVC_CONFIG: true
SCONS_CACHE_LIMIT: 4096
jobs:
windows-editor:
# Windows 10 with latest image
runs-on: "windows-latest"
# Windows Editor - checkout with the plugin
name: Editor (target=release_debug, tools=yes)
steps:
- uses: actions/checkout@v2
# Upload cache on completion and check it out now
# Editing this is pretty dangerous for Windows since it can break and needs to be properly tested with a fresh cache.
- name: Load .scons_cache directory
id: windows-editor-cache
uses: actions/cache@v2
with:
path: /.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Use python 3.x release (works cross platform; best to keep self contained in it's own step)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
# We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
- name: Compilation
env:
SCONS_CACHE: /.scons_cache/
run: |
scons tools=yes target=release_debug
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14
windows-template:
runs-on: "windows-latest"
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Upload cache on completion and check it out now
# Editing this is pretty dangerous for Windows since it can break and needs to be properly tested with a fresh cache.
- name: Load .scons_cache directory
id: windows-template-cache
uses: RevoluPowered/cache@v2.1
with:
path: /.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
continue-on-error: true
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: /.scons_cache/
run: |
scons target=release tools=no
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14

177
.gitignore vendored
View File

@ -1,27 +1,45 @@
# Godot auto generated files
*.gen.*
.import/
# Documentation generated by doxygen or from classes.xml
doc/_build/
# GoDot auto generated files
platform/server/logo.h
platform/android/logo.h
platform/bb10/logo.h
platform/iphone/logo.h
platform/javascript/logo.h
platform/nacl/logo.h
platform/osx/logo.h
platform/windows/logo.h
platform/x11/logo.h
drivers/gles2/shaders/*.h
modules/register_module_types.cpp
core/version.h
core/method_bind.inc
core/method_bind_ext.inc
core/script_encryption_key.cpp
core/global_defaults.cpp
tools/editor/register_exporters.cpp
tools/editor/doc_data_compressed.h
tools/editor/editor_icons.cpp
-fpic
.fscache
make.bat
log.txt
# Javascript specific
*.bc
# CLion
cmake-build-debug
# Android specific
.gradle
local.properties
*.iml
.idea
.gradletasknamecache
project.properties
platform/android/java/app/libs/*
platform/android/java/local.properties
platform/android/java/project.properties
platform/android/java/AndroidManifest.xml
platform/android/java/bin/*
platform/android/java/libs/*
platform/android/java/lib/.cxx/
platform/android/java/nativeSrcsConfigs/.cxx/
platform/android/java/gen/*
platform/android/java/assets
platform/android/libs/apk_expansion/bin/*
platform/android/libs/apk_expansion/gen/*
platform/android/libs/google_play_services/bin/*
platform/android/libs/google_play_services/gen/*
platform/android/libs/play_licensing/bin/*
platform/android/libs/play_licensing/gen/*
# General c++ generated files
*.lib
@ -32,59 +50,21 @@ platform/android/java/nativeSrcsConfigs/.cxx/
*.d
*.so
*.os
*.Plo
*.lo
# Binutils tmp linker output of the form "stXXXXXX" where "X" is alphanumeric
st[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]
# Libs generated files
.deps/*
.dirstamp
# Gprof output
gmon.out
# Vim temp files
*.swo
*.swp
# Qt project files
# QT project files
*.config
*.creator
*.creator.*
*.files
*.includes
*.cflags
*.cxxflags
# Code::Blocks files
*.cbp
*.layout
*.depend
# Eclipse CDT files
.cproject
.settings/
*.pydevproject
*.launch
# Geany/geany-plugins files
*.geany
.geanyprj
# Jetbrains IDEs
.idea/
# Misc
.DS_Store
__MACOSX
logs/
# for projects that use SCons for building: http://http://www.scons.org/
.sconf_temp
.sconsign*.dblite
.sconsign.dblite
*.pyc
# https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
@ -93,11 +73,6 @@ logs/
*.suo
*.user
*.sln.docstates
*.sln
*.vcxproj*
# Custom SCons configuration override
/custom.py
# Build results
[Dd]ebug/
@ -108,19 +83,11 @@ build/
bld/
[Bb]in/
[Oo]bj/
*.debug
*.dSYM
# Visual Studio cache/options directory
.vs/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# Hints for improving IntelliSense, created together with VS project
cpp.hint
#NUNIT
*.VisualState.xml
TestResult.xml
@ -144,7 +111,6 @@ TestResult.xml
*.tlh
*.tmp
*.tmp_proj
*.bak
*.log
*.vspscc
*.vssscc
@ -152,7 +118,6 @@ TestResult.xml
*.pidb
*.svclog
*.scc
*.nib
# Chutzpah Test files
_Chutzpah*
@ -164,10 +129,6 @@ ipch/
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.opendb
*.VC.VC.opendb
enc_temp_folder/
# Visual Studio profiler
*.psess
@ -214,6 +175,9 @@ AutoTest.Net/
# Installshield output folder
[Ee]xpress/
# dumpdoc generated files
doc/html/class_list
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
@ -260,23 +224,10 @@ ClientBin/
*.pfx
*.publishsettings
node_modules/
__pycache__/
# KDE
.directory
# Kdevelop project files
*.kdev4
# Kate swap files
*.kate-swp
# Xcode
xcuserdata/
*.xcscmblueprint
*.xccheckout
*.xcodeproj/*
# RIA/Silverlight projects
Generated_Code/
@ -304,19 +255,11 @@ FakesAssemblies/
# =========================
# Windows image file caches
[Tt]humbs.db
[Tt]humbs.db:encryptable
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Windows stackdumps
*.stackdump
# Windows shortcuts
*.lnk
# Folder config file
[Dd]esktop.ini
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
@ -328,7 +271,6 @@ logo.h
TAGS
!TAGS/
tags
*.tags
!tags/
gtags.files
GTAGS
@ -338,33 +280,4 @@ cscope.files
cscope.out
cscope.in.out
cscope.po.out
godot.creator.*
projects/
platform/windows/godot_res.res
# Visual Studio 2017 and Visual Studio Code workspace folder
/.vs
/.vscode
# Visual Studio Code workspace file
*.code-workspace
# Scons construction environment dump
.scons_env.json
# Scons progress indicator
.scons_node_count
# ccls cache (https://github.com/MaskRay/ccls)
.ccls-cache/
# compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
compile_commands.json
# Cppcheck
*.cppcheck
# https://clangd.llvm.org/ cache folder
.clangd/
.cache/
godot.creator.user.wd3476

140
.mailmap
View File

@ -1,140 +0,0 @@
Alexander Holland <alexander.holland@live.de>
Alexander Holland <alexander.holland@live.de> <alexander.holland@haw-hamburg.de>
Alexander Holland <alexander.holland@live.de> <AlexHolly>
Andrea Catania <info@andreacatania.com>
Anish Bhobe <anishbhobe@hotmail.com>
Anutrix <numaanzaheerahmed@yahoo.com>
Aren Villanueva <arenvillanueva@yomogi-soft.com> <aren@displaysweet.com>
Ariel Manzur <ariel@godotengine.org>
Ariel Manzur <ariel@godotengine.org> <puntob@gmail.com>
Ariel Manzur <ariel@godotengine.org> <punto@godotengine.org>
Ariel Manzur <ariel@godotengine.org> <ariel@okamstudio.com>
Ariel Manzur <ariel@godotengine.org> <punto@Ariels-Mac-mini.local>
Ariel Manzur <ariel@godotengine.org> <punto@Ariels-Mac-mini-2.local>
Bastiaan Olij <mux213@gmail.com>
Benjamin <mafortion.benjamin@gmail.com>
Bernhard Liebl <Bernhard.Liebl@gmx.org> <poke1024@gmx.de>
Bernhard Liebl <Bernhard.Liebl@gmx.org> <poke1024@gmx.org>
Bruno Lourenço <madequa@users.noreply.github.com> <bmlourenco@gmail.com>
Chaosus <chaosus89@gmail.com>
Chris Bradfield <chris@kidscancode.org> <cb@scribe.net>
Clay John <claynjohn@gmail.com>
Clay John <claynjohn@gmail.com> <clayjohn@shaw.ca>
Dana Olson <dana@shineuponthee.com> <adolson@gmail.com>
dankan1890 <mewuidev2@gmail.com>
Daniel J. Ramirez <djrmuv@gmail.com>
Dominik 'dreamsComeTrue' Jasiński <dominikjasinski@o2.pl>
Emmanuel Barroga <emmanuelbarroga@gmail.com>
Eric M <itsjusteza@gmail.com>
Eric Rybicki <info@ericrybicki.com> <stratos695@googlemail.com>
Erik Selecký <35656626+rxlecky@users.noreply.github.com>
Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@users.noreply.github.com>
Eveline Jarosz <marqin.pl@gmail.com>
Eveline Jarosz <marqin.pl@gmail.com> <marqin.pl+git@gmail.com>
Fabian <supagu@gmail.com>
Ferenc Arn <tagcup@yahoo.com>
Ferenc Arn <tagcup@yahoo.com> <tagcup@users.noreply.github.com>
foxydevloper <12120644+foxydevloper@users.noreply.github.com>
Fredia Huya-Kouadio <fhuyakou@gmail.com>
Fredia Huya-Kouadio <fhuyakou@gmail.com> <fhuya@google.com>
Geequlim <geequlim@gmail.com>
Gilles Roudiere <gilles.roudiere@gmail.com>
Gilles Roudiere <gilles.roudiere@gmail.com> <gilles.roudiere@laas.fr>
Gordon MacPherson <gordon@gordonite.tech>
Guilherme Felipe <guilhermefelipecgs@gmail.com>
Hanif Bin Ariffin <hanif.ariffin.4326@gmail.com>
HaSa1002 <johawitt@outlook.de>
Hein-Pieter van Braam-Stewart <hp@tmm.cx>
Hugo Locurcio <hugo.locurcio@hugo.pro> <hugo.l@openmailbox.org>
Hugo Locurcio <hugo.locurcio@hugo.pro> <Calinou@users.noreply.github.com>
Hugo Locurcio <hugo.locurcio@hugo.pro> Calinou <calinou@opmbx.org>
Ian Bishop <ianb96@gmail.com>
Ignacio Etcheverry <ignalfonsore@gmail.com>
Ignacio Etcheverry <ignalfonsore@gmail.com> <neikeq@users.noreply.github.com>
Ilaria Cislaghi <cislaghi.ilaria@gmail.com>
Ilaria Cislaghi <cislaghi.ilaria@gmail.com> <ilaria.cislaghi@simedis.com>
Indah Sylvia <ISylvox@yahoo.com>
J08nY <johny@neuromancer.sk> <jancar.jj@gmail.com>
J08nY <johny@neuromancer.sk> <J08nY@users.noreply.github.com>
Jakub Grzesik <kubecz3k@gmail.com>
janglee <merupatel123@gmail.com>
Jérôme Gully <jerome.gully0@gmail.com>
JFonS <joan.fonssanchez@gmail.com>
Juan Linietsky <reduzio@gmail.com>
Juan Linietsky <reduzio@gmail.com> <juan@godotengine.org>
Juan Linietsky <reduzio@gmail.com> <juan@okamstudio.com>
Juan Linietsky <reduzio@gmail.com> <reduz@Juans-MBP.fibertel.com.ar>
Juan Linietsky <reduzio@gmail.com> <red@kyoko>
Julian Murgia <the.straton@gmail.com>
Kanabenki <lucien.menassol@gmail.com> <18357657+Kanabenki@users.noreply.github.com>
Kelly Thomas <kelly.thomas@hotmail.com.au>
Kongfa Waroros <gongpha@hotmail.com>
K. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>
kleonc <9283098+kleonc@users.noreply.github.com> <kleonc@users.noreply.github.com>
Leon Krause <lk@leonkrause.com> <eska@eska.me>
Leon Krause <lk@leonkrause.com> <eska014@users.noreply.github.com>
Liz Haas <27thLiz@gmail.com>
Liz Haas <27thLiz@gmail.com> <liu.gam3@gmail.com>
Liz Haas <27thLiz@gmail.com> <hinsbart@gmail.com>
Liz Haas <27thLiz@gmail.com> <hinsbart@users.noreply.github.com>
Liz Haas <27thLiz@gmail.com> <entenflugstuhl@gmail.com>
Manuel Strey <manuel.strey@gmx.de>
Marcel Admiraal <madmiraal@users.noreply.github.com>
Marcelo Fernandez <marcelofg55@gmail.com>
Marcin Zawiejski <dragmz@gmail.com>
Marcus Elg <marcusaccounts@yahoo.se>
Mariano Javier Suligoy <marianognu.easyrpg@gmail.com>
Mario Schlack <m4r10.5ch14ck@gmail.com>
marxin <mliska@suse.cz>
marynate <mary.w.nate@gmail.com> <marynate@github.com>
Mateo Kuruk Miccino <mateomiccino@gmail.com>
Max Hilbrunner <m.hilbrunner@gmail.com>
Max Hilbrunner <m.hilbrunner@gmail.com> <mhilbrunner@users.noreply.github.com>
Michael Alexsander <michaelalexsander@protonmail.com>
Nathan Franke <natfra@pm.me> <nathanwfranke@gmail.com>
Nathan Lovato <nathan@gdquest.com>
Nathan Warden <nathan@nathanwarden.com> <nathanwardenlee@icloud.com>
Nicholas Huelin <62965063+SirQuartz@users.noreply.github.com>
Nils ANDRÉ-CHANG <nils@nilsand.re>
Nils ANDRÉ-CHANG <nils@nilsand.re> <nils.andre.chang@gmail.com>
Nuno Donato <nunodonato@gmail.com> <n.donato@estrelasustentavel.pt>
Pawel Kowal <pkowal1982@gmail.com>
Pedro J. Estébanez <pedrojrulez@gmail.com> <RandomShaper@users.noreply.github.com>
Paul Batty <p_batty@hotmail.co.uk>
Paul Batty <p_batty@hotmail.co.uk> <Paulb23@users.noreply.github.com>
Pawel Kowal <pkowal1982@gmail.com> <pawel.kowal@javart.eu>
Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
Pieter-Jan Briers <pieterjan.briers+git@gmail.com> <pieterjan.briers@gmail.com>
Poommetee Ketson <poommetee@protonmail.com>
Przemysław Gołąb (n-pigeon) <golab.przemyslaw@gmail.com>
Rafał Mikrut <mikrutrafal@protonmail.com>
Rafał Mikrut <mikrutrafal@protonmail.com> <mikrutrafal54@gmail.com>
Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@posteo.de>
Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@users.noreply.github.com>
Ramesh Ravone <ramesh.maran443@gmail.com>
RaphaelHunter <raphael10241024@gmail.com>
RaphaelHunter <raphael10241024@gmail.com> <Raphael10241024@gmail.com>
RaphaelHunter <raphael10241024@gmail.com> <raphael20141024@gmail.com>
Rémi Verschelde <rverschelde@gmail.com> <remi@verschelde.fr>
Rhody Lugo <rhodylugo@gmail.com> <rhodylugo@me.com>
Ricardo Subtil <ricasubtil@gmail.com>
Robin Hübner <profan@prfn.se> <robinhubner@gmail.com>
romulox_x <romulox_x@yahoo.com>
Ruslan Mustakov <r.mustakov@gmail.com> <ruslan.mustakov@xored.com>
Saracen <SaracenOne@gmail.com>
sheepandshepherd <sheepandshepherd@hotmail.com> <sheepandshepherd@users.noreply.github.com>
Swarnim Arun <swarnimarun11@gmail.com>
Theo Hallenius <redsymbzone@hotmail.com>
Thomas Herzog <therzog@mail.de>
Thomas Herzog <therzog@mail.de> <thomas.herzog@mail.com>
Thomas Herzog <therzog@mail.de> <thomas.herzog@simedis.com>
Tomasz Chabora <kobewi4e@gmail.com>
Twarit <wtwarit@gmail.com>
V.VamsiKrishna <vk@bsb.in> <vamsikrishna.v@gmail.com>
Wilhem Barbier <nounoursheureux@openmailbox.org> <wilhem.b@free.fr>
Wilhem Barbier <nounoursheureux@openmailbox.org> <schtroumps31@gmail.com>
Will Nations <willnationsdev@gmail.com>
yg2f <yoann@terminajones.com>
Yuri Sizov <yuris@humnom.net> <pycbouh@users.noreply.github.com>
Zak Stam <zakscomputers@hotmail.com>
Zher Huei Lee <lee.zh.92@gmail.com>

14
.travis.yml Normal file
View File

@ -0,0 +1,14 @@
language: cpp
compiler:
- gcc
before_install:
before_script:
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
- sudo apt-get update -qq
- sudo apt-get install -qq scons pkg-config libx11-dev libxcursor-dev build-essential libasound2-dev libfreetype6-dev libgl1-mesa-dev libglu-dev
- if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.8; fi
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi
script: scons platform=x11

View File

@ -1,221 +0,0 @@
# Godot Engine authors
Godot Engine is developed by a community of voluntary contributors who
contribute code, bug reports, documentation, artwork, support, etc.
It is impossible to list them all; nevertheless, this file aims at listing
the developers who contributed significant patches to this MIT licensed
source code. "Significant" is arbitrarily decided, but should be fair :)
GitHub usernames are indicated in parentheses, or as sole entry when no other
name is available.
## Project Founders
Juan Linietsky (reduz)
Ariel Manzur (punto-)
## Lead Developer
Juan Linietsky (reduz)
## Project Manager
Rémi Verschelde (akien-mga)
## Developers
(in alphabetical order, with over 10 commits excluding merges)
Aaron Franke (aaronfranke)
Aaron Record (LightningAA)
Alexander Holland (AlexHolly)
Alexey Khoroshavin (allkhor)
Alket Rexhepi (alketii)
Andrea Catania (AndreaCatania)
Andrii Doroshenko (Xrayez)
Andy Moss (MillionOstrich)
Angad Kambli (angad-k)
Anilforextra (AnilBK)
Anish Bhobe (KidRigger)
Anton Yabchinskiy (a12n)
Anutrix
Aren Villanueva (kurikaesu)
Ariel Manzur (punto-)
Bastiaan Olij (BastiaanOlij)
Ben Brookshire (sheepandshepherd)
Benjamin Larsson (Nallebeorn)
Bernard Liebl (poke1024)
Bhuvan Vemula (Bhu1-V)
Błażej Szczygieł (zaps166)
Bojidar Marinov (bojidar-bg)
Bruno Lourenço (MadEqua)
bruvzg
Cameron Reikes (creikey)
Camille Mohr-Daurat (pouleyKetchoupp)
Carl Olsson (not-surt)
Carter Anderson (cart)
Chris Bradfield (cbscribe)
Clay John (clayjohn)
Dana Olson (adolson)
Daniel J. Ramirez (djrm)
Daniel Rakos (aqnuep)
dankan1890
Danil Alexeev (dalexeev)
David Sichma (DavidSichma)
David Snopek (dsnopek)
Dharkael (lupoDharkael)
Dmitry Koteroff (Krakean)
Dominik Jasiński (dreamsComeTrue)
DualMatrix
Ellen Poe (ellenhp)
Emmanuel Barroga (codecustard)
Emmanuel Leblond (touilleMan)
Eoin O'Neill (Eoin-ONeill-Yokai)
Eric Lasota (elasota)
Eric M (EricEzaM)
Eric Rybicki (ericrybick)
Erik Selecký (rxlecky)
est31
Eveline Jarosz (Marqin)
Fabian Mathews (supagu)
Fabio Alessandrelli (Faless)
fabriceci
Ferenc Arn (tagcup)
follower
foxydevloper
François Belair (Razoric480)
Franklin Sobrinho (TheHX)
Fredia Huya-Kouadio (m4gr3d)
Geequlim
George Marques (vnen)
Gerrit Großkopf (Grosskopf)
Gilles Roudiere (groud)
Gordon MacPherson (RevoluPowered)
Guilherme Felipe de C. G. da Silva (guilhermefelipecgs)
Hanif Bin Ariffin (hbina)
Haoyu Qiu (timothyqiu)
Hein-Pieter van Braam-Stewart (hpvb)
Hendrik Brucker (Geometror)
hilfazer
Hiroshi Ogawa (hi-ogawa)
homer666
hoontee
Hugo Locurcio (Calinou)
Ian Bishop (ianb96)
Ibrahn Sahir (ibrahn)
Ignacio Etcheverry (neikeq)
Ilaria Cislaghi (QbieShay)
Indah Sylvia (ISylvox)
J08nY
Jakub Grzesik (kubecz3k)
James Buck (jbuck3)
Jean-Michel Bernard (jmb462)
Jérôme Gully (Nutriz)
Jia Jun Chai (SkyLucilfer)
Joan Fons Sanchez (JFonS)
Johannes Witt (HaSa1002)
Johan Manuel (29jm)
Joshua Grams (JoshuaGrams)
Juan Linietsky (reduz)
Julian Murgia (StraToN)
Julien Nguyen (Blackiris)
Jummit
Justo Delgado (mrcdk)
Kelly Thomas (KellyThomas)
kleonc
Kongfa Waroros (gongpha)
Kostadin Damyanov (Max-Might)
K. S. Ernest (iFire) Lee (fire)
lawnjelly
Leon Krause (leonkrause)
Liz Haas (27thLiz)
Lucien Menassol (Kanabenki)
Lyuma
m4nu3lf
Maganty Rushyendra (mrushyendra)
Marcel Admiraal (madmiraal)
Marcelo Fernandez (marcelofg55)
Marc Gilleron (Zylann)
Marcin Zawiejski (dragmz)
Marcus Brummer (mbrlabs)
Marcus Elg (MCrafterzz)
Mariano Javier Suligoy (MarianoGnu)
Mario Schlack (hurikhan)
Martin Capitanio (capnm)
Martin Liška (marxin)
Martin Sjursen (binbitten)
marynate
Masoud BH (masoudbh3)
Mateo Kuruk Miccino (kuruk-mm)
Matthew (skyace65)
Matthias Hölzl (hoelzl)
Max Hilbrunner (mhilbrunner)
merumelu
Meru Patel (Janglee123)
Michael Alexsander (YeldhamDev)
MichiRecRoom (LikeLakers2)
mrezai
muiroc
Nathan Franke (nathanfranke)
Nathan Lovato (NathanLovato)
Nathan Warden (NathanWarden)
Nicholas Huelin (SirQuartz)
Nils André-Chang (NilsIrl)
Noah Beard (TwistedTwigleg)
Nuno Donato (nunodonato)
Ovnuniarchos
Pascal Richter (ShyRed)
Patrick (firefly2442)
Paul Batty (Paulb23)
Paul Joannon (paulloz)
Paul Trojahn (ptrojahn)
Pawel Kowal (pkowal1982)
Pedro J. Estébanez (RandomShaper)
Pieter-Jan Briers (PJB3005)
Poommetee Ketson (Noshyaar)
Przemysław Gołąb (n-pigeon)
Rafał Mikrut (qarmin)
Ralf Hölzemer (rollenrolm)
Ramesh Ravone (RameshRavone)
raphael10241024
Ray Koopa (RayKoopa)
Rémi Verschelde (akien-mga)
Rhody Lugo (rraallvv)
Ricardo Subtil (Ev1lbl0w)
Roberto F. Arroyo (robfram)
Robin Hübner (profan)
romulox-x
Ruslan Mustakov (endragor)
Ryan Roden-Corrent (rrcore)
Saniko (sanikoyes)
santouits
SaracenOne
Sergey Minakov (naithar)
sersoong
Shiqing (kawa-yoiko)
Simon Wenner (swenner)
Stijn Hinlopen (hinlopen)
Swarnim Arun (minraws)
Thakee Nathees (ThakeeNathees)
thebestnom
Theo Hallenius (TheoXD)
Thomas Herzog (karroffel)
Timo Schwarzer (timoschwarzer)
Timo (toger5)
Tomasz Chabora (KoBeWi)
Twarit Waikar (IronicallySerious)
Umang Kalra (theoway)
Vinzenz Feenstra (vinzenz)
박한얼 (volzhs)
V. Vamsi Krishna (vkbsb)
Wilhem Barbier (nounoursheureux)
Will Nations (willnationsdev)
Wilson E. Alvarez (Rubonnek)
Xavier Cho (mysticfall)
yg2f (SuperUserNameMan)
Yuri Roubinsky (Chaosus)
Yuri Sizov (pycbouh)
Zak Stam (zaksnet)
Zher Huei Lee (leezh)
ZuBsPaCe

File diff suppressed because it is too large Load Diff

View File

@ -1,234 +0,0 @@
# How to contribute efficiently
## Table of contents
- [Reporting bugs](#reporting-bugs)
- [Proposing features or improvements](#proposing-features-or-improvements)
- [Contributing pull requests](#contributing-pull-requests)
- [Contributing to Godot's translation](#contributing-to-godots-translation)
- [Communicating with developers](#communicating-with-developers)
**Please read the first section before reporting a bug!**
## Reporting bugs
The golden rule is to **always open *one* issue for *one* bug**. If you notice
several bugs and want to report them, make sure to create one new issue for
each of them.
If you're reporting a new bug, you'll make our life simpler (and the
fix will come sooner) by following these guidelines:
### Search first in the existing database
Issues are often reported several times by various users. It's good practice to
**search first in the [issue tracker](https://github.com/godotengine/godot/issues)
before reporting your issue**. If you don't find a relevant match or if you're
unsure, don't hesitate to **open a new issue**. The bugsquad will handle it
from there if it's a duplicate.
### Specify the platform
Godot runs on a large variety of platforms and operating systems and devices.
**In your bug reports, please always specify:**
- Operating system and version (e.g. Windows 10, macOS 10.15, Ubuntu 19.10)
- Godot version (e.g. 3.2, 3.1.2, or the Git commit hash if you're using a development branch)
For bugs that are likely OS-specific and/or graphics-related, please also specify:
- Device (CPU model including architecture, e.g. x86, x86_64, ARM, etc.)
- GPU model (and the driver version in use if you know it)
**Bug reports not including the required information may be closed at the
maintainers' discretion.** If in doubt, always include all the requested
information; it's better to include too much information than not enough
information.
### Specify steps to reproduce
Many bugs can't be reproduced unless specific steps are taken. Please **specify
the exact steps** that must be taken to reproduce the condition, and try to
keep them as minimal as possible. If you're describing a procedure to follow
in the editor, don't hesitate to include screenshots.
Making your bug report easy to reproduce will make it easier for contributors
to fix the bug.
### Provide a simple, example project
Sometimes, unexpected behavior can happen in your project. In such case,
understand that:
- What happens to you may not happen to other users.
- We can't take the time to look at your project, understand how it is set up
and then figure out why it's failing.
To speed up our work, **please upload a minimal project** that isolates
and reproduces the issue. This is always the **best way for us to fix it**.
You can attach a ZIP file with the minimal project directly to the bug report,
by drag and dropping the file in the GitHub edition field.
We recommend always attaching a minimal reproduction project, even if the issue
may seem simple to reproduce manually.
**If you've been asked by a maintainer to upload a minimal reproduction project,
you *must* do so within 7 days.** Otherwise, your bug report will be closed as
it'll be considered too difficult to diagnose.
Now that you've read the guidelines, click the link below to create a
bug report:
- **[Report a bug](https://github.com/godotengine/godot/issues/new?assignees=&labels=&template=bug_report.md&title=)**
## Proposing features or improvements
**Since August 2019, the main issue tracker no longer accepts feature proposals.**
Instead, head to the [Godot Proposals repository](https://github.com/godotengine/godot-proposals)
and follow the instructions in the README file. High-quality feature proposals
are more likely to be well-received by the maintainers and community, so do
your best :)
See [this article](https://godotengine.org/article/introducing-godot-proposals-repository)
for detailed rationale on this change.
## Contributing pull requests
If you want to add new engine features, please make sure that:
- This functionality is desired, which means that it solves a common use case
that several users will need in their real-life projects.
- You talked to other developers on how to implement it best. See also
[Proposing features or improvements](#proposing-features-or-improvements).
- Even if it doesn't get merged, your PR is useful for future work by another
developer.
Similar rules can be applied when contributing bug fixes - it's always best to
discuss the implementation in the bug report first if you are not 100% about
what would be the best fix.
[This blog post](https://godotengine.org/article/will-your-contribution-be-merged-heres-how-tell)
outlines the process used by core developers when assessing PRs. We strongly
recommend that you have a look at it to know what's important to take into
account for a PR to be considered for merging.
In addition to the following tips, also take a look at the
[Engine development guide](https://docs.godotengine.org/en/latest/development/cpp/)
for an introduction to developing on Godot.
The [Contributing docs](https://docs.godotengine.org/en/latest/community/contributing/index.html)
also have important information on the PR workflow and the code style we use.
### Document your changes
If your pull request adds methods, properties or signals that are exposed to
scripting APIs, you **must** update the class reference to document those.
This is to ensure the documentation coverage doesn't decrease as contributions
are merged.
[Update the documentation template](https://docs.godotengine.org/en/latest/community/contributing/updating_the_class_reference.html#updating-the-documentation-template)
using your compiled binary, then fill in the descriptions.
Follow the style guide described in the
[Docs writing guidelines](https://docs.godotengine.org/en/latest/community/contributing/docs_writing_guidelines.html).
If your pull request modifies parts of the code in a non-obvious way, make sure
to add comments in the code as well. This helps other people understand the
change without having to look at `git blame`.
### Be nice to the Git history
Try to make simple PRs that handle one specific topic. Just like for reporting
issues, it's better to open 3 different PRs that each address a different issue
than one big PR with three commits.
When updating your fork with upstream changes, please use ``git pull --rebase``
to avoid creating "merge commits". Those commits unnecessarily pollute the git
history when coming from PRs.
Also try to make commits that bring the engine from one stable state to another
stable state, i.e. if your first commit has a bug that you fixed in the second
commit, try to merge them together before making your pull request (see ``git
rebase -i`` and relevant help about rebasing or amending commits on the
Internet).
This [Git style guide](https://github.com/agis-/git-style-guide) has some
good practices to have in mind.
See our [PR workflow](https://docs.godotengine.org/en/latest/community/contributing/pr_workflow.html)
documentation for tips on using Git, amending commits and rebasing branches.
### Format your commit messages with readability in mind
The way you format your commit messages is quite important to ensure that the
commit history and changelog will be easy to read and understand. A Git commit
message is formatted as a short title (first line) and an extended description
(everything after the first line and an empty separation line).
The short title is the most important part, as it is what will appear in the
`shortlog` changelog (one line per commit, so no description shown) or in the
GitHub interface unless you click the "expand" button. As the name says, try to
keep that first line under 72 characters. It should describe what the commit
does globally, while details would go in the description. Typically, if you
can't keep the title short because you have too much stuff to mention, it means
you should probably split your changes in several commits :)
Here's an example of a well-formatted commit message (note how the extended
description is also manually wrapped at 80 chars for readability):
```text
Prevent French fries carbonization by fixing heat regulation
When using the French fries frying module, Godot would not regulate the heat
and thus bring the oil bath to supercritical liquid conditions, thus causing
unwanted side effects in the physics engine.
By fixing the regulation system via an added binding to the internal feature,
this commit now ensures that Godot will not go past the ebullition temperature
of cooking oil under normal atmospheric conditions.
Fixes #1789, long live the Realm!
```
**Note:** When using the GitHub online editor or its drag-and-drop
feature, *please* edit the commit title to something meaningful. Commits named
"Update my_file.cpp" won't be accepted.
## Contributing to Godot's translation
You can contribute to Godot's translation from the [Hosted
Weblate](https://hosted.weblate.org/projects/godot-engine/godot), an open
source and web-based translation platform. Please refer to the [translation
readme](editor/translations/README.md) for more information.
You can also help translate [Godot's
documentation](https://hosted.weblate.org/projects/godot-engine/godot-docs/)
on Weblate.
## Communicating with developers
The Godot Engine community has [many communication
channels](https://godotengine.org/community), some used more for user-level
discussions and support, others more for development discussions.
To communicate with developers (e.g. to discuss a feature you want to implement
or a bug you want to fix), the following channels can be used:
- [Godot Contributors Chat](https://chat.godotengine.org): You will
find most core developers there, so it's the go-to platform for direct chat
about Godot Engine development. Feel free to start discussing something there
to get some early feedback before writing up a detailed proposal in a GitHub
issue.
- [Bug tracker](https://github.com/godotengine/godot/issues): If there is an
existing issue about a topic you want to discuss, just add a comment to it -
many developers watch the repository and will get a notification. You can
also create a new issue - please keep in mind to create issues only to
discuss quite specific points about the development, and not general user
feedback or support requests.
- [Feature proposals](https://github.com/godotengine/godot-proposals/issues):
To propose a new feature, we have a dedicated issue tracker for that. Don't
hesitate to start by talking about your idea on the Godot Contributors Chat
to make sure that it makes sense in Godot's context.
Thanks for your interest in contributing!
—The Godot development team

File diff suppressed because it is too large Load Diff

823
DONORS.md
View File

@ -1,823 +0,0 @@
# Donors to the Godot Engine project
Godot Engine is a non-profit project developed by a community of voluntary
contributors, as well as occasional paid contributors thanks to the financial
support of generous donors.
The ways to donate to the project, as well as details on how the funds are
used, are described on [Godot's website](https://godotengine.org/donate).
The following is a list of the current monthly donors, who will have their
generous deed immortalized in the next stable release of Godot Engine.
## Platinum sponsors
Gamblify <https://www.gamblify.com>
Heroic Labs <https://heroiclabs.com>
Spiffcode <http://www.spiffcode.com>
## Gold sponsors
None currently, become one! <https://godotengine.org/donate>
## Silver sponsors
ASIFA-Hollywood <https://www.asifa-hollywood.org>
## Bronze sponsors
Ben Nolan
Brandon Lamb
Garry Newman
Gordon MacPherson
Hunter Dickson
Kitcat490
Kyle Szklenski
Moonwards <https://www.moonwards.com>
TrampolineTales <http://trampolinetales.com>
## Mini sponsors
AD Ford
alex brown
Andrew Bowen
Andrew Dunai
Angry Skull
anti666
blurp
Christian Baune
Christopher Montesano
Christopher Shifflett
Daniel Edwards
Darrin Massena
David Mydlarz
Digital Grows
Dov Zimring
Edward Flick
Florian Neumann
Gamechuck
GameDev.net
Hein-Pieter van Braam
Jasper Brooks
Jay Sistar
Jeffery Chiu
John G Gentzel
Jonah Stich
Justin Arnold
Justo Delgado Baudí
Marcel Kräml
Marek Belski
Matthieu Huvé
Maxim Karsten
Mike King
Nathan Warden
Neal Gompa (Conan Kudo)
Ninja_5tyl3
Patrick Horn
Patrick Schmidt
Rami
Relintai
Ronnie Cheng
Slobodan Milnovic
Stephan Lanfermann
Steve
Stonesoft io
Thomas Krampl
Tristan Pemble
Violin Iliev
Xwdit
## Gold donors
Acheron
Adam Brown
albinaask
Andres Hernandez
Arisaka Mayuki
Asher Glick
Barugon
Benito
Carlo Cabanilla
Daniel James
David Gehrig
David Graham
David Snopek
Ed Morley
Ellen Poe
Florian Rämisch
Gamejunkey
Jacobus Dens
Jakub Grzesik
Javier Roman
Joan Fons
Johnny IV Young
Jonathan Wright
Jon Woodward
Karl Werf
Klavdij Voncina
kuku
Lex Steers
Maciej Pendolski
Manuele Finocchiaro
Markus Wiesner
Matthew Hillier
Michael
Mick
Monster Vial
Officine Pixel S.n.c.
Patrick Brock
Pedro Silva
Petrus Prinsloo
Retro Village
Rob Messick
Roland Fredenhagen
Ronan Zeegers
Sarksus
Scott B
Sean
segfault-god
Sergey
Sofox
Stephan Kessler
Stephen Molyneaux
Taylor Ritenour
Tom Langwaldt
Tricky Fat Cat
tukon
Vagabond Arcade
Vitaliy Sapronenko
Xeno Coliseum
Zaven Muradyan
Adam Nakonieczny
Adam Nelson
Alexander Erlemann
Alexander J Maynard
Alex Khayrullin
alice gambrell
Andrew Cunningham
Andrew Farr
Andriy
Antanas Paskauskas
Antoni Batchelli
Arch Henderson III
Arthur S. Muszynski
Ben Botwin
Brandon Hawkinson
Caleb Sizemore
Cameron Connolly
Charlie Whitfield
Chase Taranto
Chelsea Hash
Chris Petrich
Chris Serino
Christian Leth Jeppesen
Cow
Craig Ostrin
Craig Scarborough
Craig Smith
Cristopher
CzechBlueBear
D
dan didenko
Daniel Hernández Alcojor
Daniel Tebbutt
Darrian Little
Dennis Belfrage
Dimitri Nüscheler
Donn Eddy
Edgar Sun
Eric
Eric Brand
Eugenio Hugo Salgüero Jáñez
EXUREI
flesk
foxydevloper
Fransiska
Gabrielius Vaiškūnas
Gary Hulst
gavlig
General Chicken
Geoffroy Warin
GGGames.org
gisora
GrayDwarf
Guilherme Felipe de C. G. da Silva
Harvey Fong
Hayden Whitehead
Heath Hayes
Horváth Péter
Hu Hund
Hunter Barabas
Jake Burga
James Couzens
James Zahn
Jan Sælid
Jared
Jared White
Jennifer Wilcox
Jesús Chicharro
Joel Fivat
Johnathan Kupferer
Jonathan Turner
Josef Stumpfegger
Jose Malheiro
Jose Manuel Muñoz Perez
Joseph Crane
Joshie Sparks
Joshua Flores
Joshua Lesperance
Juan Velandia
Judd
Julián Absatz
Julian Todd
Juraj Móza
JUSTIN CARROLL
Kelteseth
kickmaniac
kinfox
Kis Levente Lorand
Kos
Laszlo Kiss
leetNightshade
Leo Fidel R Liban
Liam Smyth
LoparPanda
Luca Vazzano
Luke
MadScientistCarl
Marcus Dobler
Marcus Richter
Mark Barrett
Martin Eigel
Martin Kotz
Martin Soucek
matt
Matt Greene
Matthew Hall
Matthias Toepp
Mecha Kaiju X
medecau
Michael
Michael Bordießer-Krauth
Michael Dürwald
Michael Policastro
MightyPossum
MikadoSC
Mike Barbee
minz1
nate etan
Nick Abousselam
Nicola Cocchiaro
Nicole Barovic
Nikita Bliznyuk
Oliver Dick
Oscar Campos
Paul Hocker
Paul Von Zimmerman
Pavel Kotlyar
Pete Goodwin
Petr Malac
PhaineOfCatz
Piotr Wyszyński
Pyxl
Raymond Harris
Rene Tailleur
Rhodochrone
Rob
Robert McDermott
Robert Willes
Rob McInroy
Rocknight Studios
Rodrigo Favarete
Romeo Disca
Ronnie Ashlock
Ronny Mühle
Ryan Scott
Samuel Hummerstone
Samuel Judd
Samuel Smart
Sean Morgan
Sebastian Hutter
Sébastien
Serban Serafimescu
Sergey Fonaryov
Sergey Minakov
Shishir Tandale
Sing Chun Lee
SKison
Song Junwoo
spacechase0
Stephan Hennion
Steven Landow
Stoned Xander
Super Izzo
Sven F.
Thomas Bjarnelöf
Thomas Kurz
Tim Howard
Tobias Bocanegra
Tobias Raggl
Todd Smith
Torbulous
toto bibi
Troy Kinsella
Turntsnaco
tweaklab
Valryia
VikFro
Vincent Cloutier
Vlad Ceru Opran
VoidPointer
Winston
Wojciech Chojnacki
xzibiting
Yifan Lai
Yuancheng Zhang
Zie Weaver
## Silver donors
1D_Inc
Aaron Oldenburg
A. B.
Actual_Dio
Adam Brunnmeier
Adam Carr
Adam Long
Adam McCurdy
Adam N Webber
Adam R Pope
Adam Smeltzer
Adam Szymański
Adisibio
Adrien de Pierres
Ahmet Kalyoncu
Aidan O'Flannagain
Aki Mimoto
Alan Beauchamp
Alberto Salazar Muñoz
Alberto Vilches
Albin Jonasson Svärdsby
Alder Stefano
AleMax
Ales Jelovcan
Alessandro Senese
Alexander Ravenheart
Alexander Walter (SilvanuZ)
Alex Chan
Alex Clavelle
alex raeside
Alex (Well Done Games)
Allan Davis
Allen Schade
Aloehart
Anders Marstein Kruke
Andre Stackhouse
Andrew Groot
andrew james morris
Andrew Thomas
Ano Nim
Anthony Avina
Anton Bouwer
Antti Vesanen
Arch Toasty
Arda Erol
Armin Preiml
Arseniy M
Arthur Brainville
Ashley Claymore
Astier Mickael
Aubrey Falconer
aurelien condomines
AzulCrescent
Balázs Batári
Baptiste Le Bourhis
Bartosz Bielecki
Benedikt
Benoit Jauvin-Girard
Ben Ridley
Ben Vercammen
Bernd Jänichen
Bernhard Werner
Bill Thibault
bitbrain
Bjarne Voigtländer
Black Block
blackjacksike
Blair Allen
Blunderjack
Bobby CC Wong
Borkzilla
Bram
brian
Brian Klein
Brodie Fairhall
Bronson Zgeb
Bruno Hurth
Burney Waring
bwhirt
Caleb Gartner
Caleb Makela
Cameron Meyer
Carlos Cejudo
Carlos Rios
Carl van der Geest
Casey
Cassidy James
Cédric Givord
Chad Steadman
Chris Chapin
Chris Langford
Christian Clavet
Christian Mauduit
Christian Winter
Christoffer Dahlblom
Christophe Gagnier
Christopher Chin
Chris Truebe
Cody Parker
Conall O
Conner Lane
Corchari
Craig Maloney
Craig Post
C. R. Messen
damucz
Daniel Cheney
Daniel Johnson
Daren Scot Wilson
Dave Walker
David Baker
David Bôle
David May
David Maziarka
David Rapisarda
deadwithbread
Devin Carraway
Diego Pereira
Dima Fedotov
Dimitri Roche
Dmitry Fisher
Dmytro Korchynskyi
Dominik Wetzel
Don B
Douglas Plumley
Dragontrapper
Dr Ewan Murray
Dr.Raccoon
Duobix
Duodecimal
DurrDiss
Eduardo Teixeira
Edward Herbert
Edward Swartz
Egon Elbre
Elgenzay
Elias Nykrem
Emerson MX
Ephemeral
Eric Stokes
Eric Walkingshaw
Eric Williams
Erkki Seppälä
Faisal Alkubaisi
Fancy Ants Studios
fby
Fekinox
Felix Bohmann
Filip Lundby
Forty Doubleu
Francisco Garcia Florez
Francois Holland
Frank
FrostMarble
Game Endeavor
Gary Thomas
George Marques
Georgi Petkov
Graham Overby
Green Fox
Greg Lincoln
Greg Olson
Greyson Richey
Grid
Grominet
Guillaume Pham Ngoc
Guldoman
Hal A
Hayden Foley
Heribert Hirth
Houdini Blueprints
Hunter Jones
Ian ORourke
Ian Williams
IndustrialRobot
Ivan Nikolaev
iveks
Jackson Harmer
Jacob D
Jaguar
Jake D
Jake Huxell
Jako Danar
James
James A F Manley
James Gary
James Guardino
James Quincy
James Thomas
Jamie Massey
Janis Skuja
Jan Vetulani
JARKKO PARVIAINEN
Jason Bolton
Jason Malcolm-Herzmark
Jason Uechi
Jeff Hungerford
Jeff Messer
Jeffrey Berube
Jennifer Graves
JernauGurgeh
Jesse Dubay
Jim Engstrand
Joe Klemmer
Joel Höglund
John Bruce
John Gabriel
John Szevin
Jonah Branch
Jonas
Jonas Arndt
Jonas Bernemann
Jonas Rudlang
Jonas Yamazaki
Jonatan R
Jonathan Bieber
Jonathan G
Jon Bonazza
Jon Sully
Jordan West
Jordy Goodridge
Jorge Antunes
Jorge Araya Navarro
Jose C. Rubio
Joseph Catrambone
Josh Taylor
Joshua Heidrich
jromkjrom
Juanfran
Juan Maggi
Juan Uys
Jueast
Julian Murgia
June Little
Justin Hamilton
Justin Hurst
Justin Oaksford
Justin Spedding
KaDokta
Karol Porzycki
Keedong Park
Keinan Powers
Keith Bradner
Kenji Kawabata
Ken Minardo
Kent Jofur
Ketafuki
Kevin van Rooijen
Kiri Jolly
Kjetil Haugland
Kodera Software
Kolandrious
Konstantin Goncharov
kormai
Kquona
Krishna Nadoor
Kristian Nygaard Jensen
KR McGinley
Kronarq
KsyTek Games
kycho
Kyle Burnett
Kyle Jacobs
Kyuppin
Lasse le Dous
Laurent CHEA
Laxman Pradhan
LEMMiNO
Leonardo Dimano
Lin Chear
Linus Lind Lundgren
Ludovic DELVAL
Luigi Renna
Luis Gaemperle
Luis M
LunaticInAHat
Major Haul
Malcolm
Marco Lardelli
Mark Jad
Mark Malone
Markus Martin
Markus Michael Egger
Markus Ort
Martin FIbik
Martin Holas
Martin Liška
Martin Trbola
Martin Zabinski
Mathieu
Matt Edwards
Matthew Booe
Matt Sylvia
Maverick
Max Fiedler
Maxime Blade
Maxwell
Melissa Mears
Merlyn Morgan-Graham
mewin
mhilbrunner
Michael
Michael Bruce-Lockhart
Michael Haney
Michael Morrison
Michał Skwarek
Michel Candries
MidoriBunn 'tis BS
Mikayla
Mike
Mike Birkhead
Mike Copley
Mitchell
Mitchell J. Wagner
MJacred
ModularMind
Molinghu
Molly Jameson
MoltenGears
MrAZIE
Mrjemandem
Nathan Fish
Nathaniel
nee
neighty
Neil Blakey-Milner
Neil Wang
Nerdforge
Nerdyninja
Nicholas La Roux
Nicholas Orlowski
Nick Eldrenkamp
Nick Macholl
Niclas Eriksen
Nicolas Goll-Perrier
Nicolas Rosset
Nicolas SAN AGUSTIN
Nils Nordmark
Nima Farid
Noel Billig
NZ
oceoh
Okatima
Oleg Reva
Oriol Muñoz Princep
oscar1000108
Oscar Domingo
Pascal
Patrick Nafarrete
Paul Gieske
Paweł Kowal
Paweł Łyczkowski
Peter Höglund
Philip Cohoe
Philip Ludington (MrPhil)
Pierre Caye
pj
Point08
Preethi Vaidyanathan
pwab
RabidTunes
Rackat
RackBar Dingum
Rad Cat
Rafa Laguna
Raffaele Aramo
Rainer Amler
Rami Hanano
Rammeow
Remi Rampin
Reneator
René Habermann
Riccardo Marini
Richard Hayes
Richard Ivánek
Richard Néveri
Riley
Rob Ruana
Rodrigo Loli
Roger Smith
Roglozor
Roland Rząsa
Roman Tinkov
Ronald Ho Hip (CrimsonZA)
Ronan
Roy Scayged
Ryan
Ryan Groom
Sam Caulfield
Sam Edson
Scott Longley
Sean Lynch
Sebastian Michailidis
SeongWan Kim
SeungJong k
Shaidak
Shane
Shane Sicienski
Shane Spoor
Silver1063
simdee
Simon Jonas Larsen
Simon Schoenenberger
Simon Wenner
sirn
Skalli
smbe19
smo1704
Solene Waked
Sophie Winter
Spencer Everhart
Squirrel
Stéphane Roussel
Steve Cloete
Steven Drovie
summerblind
Sung soo Choi
Svenne Krap
SxP
tadashi endo
Tarch
Terry
the9thdude
The Domis4
Theodore Lindsey
TheVoiceInMyHead
thomas
Thomas Bechtold
Thomas Detoy
Tianren Qin
Till1805
Tim Drumheller
Tim Erskine
Tim Gleason
Timothy B. MacDonald
Title Plinsut
TMoney
Toadile
Tobias Bradtke
Tom Coxon
Tom Webster
Torgeir Lilleskog
Torsten Crass
toupeira
Travis O'Brien
Trent Skinner
tril zerobyte
Triumph263 .
Troy Bonneau
Tryggve Sollid
Turgut Temucin
Tyler Stafos
UltyX
Uther
v01tech
Vaughan Ling
Victor
Vincent Foulon
Vi Watch
Vladimir Savin
Vladislav Smirnov
VoxelVisions.com
Vytenis Narušis
werner mendizabal
Wiley Thompson
William Edwards
William F Siqueira
William Hogben
Wyatt Goodin
x1212
xenomat
Yan Shi
Yegor Smirnov
Zak Stephens
Zher Huei Lee
蕭惟允
貴宏 小松
郝晨煜
## Bronze donors
There are even more donors that support the project with a small monthly donation.
Every bit counts and we thank every one of them for their amazing support!

View File

@ -38,7 +38,7 @@ PROJECT_NAME = Godot
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER =
PROJECT_NUMBER =
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@ -51,14 +51,14 @@ PROJECT_BRIEF = "Game Engine MIT"
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
PROJECT_LOGO = ../logo.png
PROJECT_LOGO = E:/development/godot/logo_small.png
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = ./_build/doxygen/
OUTPUT_DIRECTORY = E:/development/godot/doxygen
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@ -162,7 +162,7 @@ FULL_PATH_NAMES = YES
# will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
STRIP_FROM_PATH =
STRIP_FROM_PATH =
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
@ -171,7 +171,7 @@ STRIP_FROM_PATH =
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.
STRIP_FROM_INC_PATH =
STRIP_FROM_INC_PATH =
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
# less readable) file names. This can be useful is your file systems doesn't
@ -238,13 +238,13 @@ TAB_SIZE = 4
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines.
ALIASES =
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.
TCL_SUBST =
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
@ -291,7 +291,7 @@ OPTIMIZE_OUTPUT_VHDL = NO
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
# the files are not read by doxygen.
EXTENSION_MAPPING =
EXTENSION_MAPPING =
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
@ -632,7 +632,7 @@ GENERATE_DEPRECATEDLIST= YES
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
# ... \endcond blocks.
ENABLED_SECTIONS =
ENABLED_SECTIONS =
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
# initial value of a variable or macro / define can have for it to appear in the
@ -674,7 +674,7 @@ SHOW_NAMESPACES = YES
# by doxygen. Whatever the program writes to standard output is used as the file
# version. For an example see the documentation.
FILE_VERSION_FILTER =
FILE_VERSION_FILTER =
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
# by doxygen. The layout file controls the global structure of the generated
@ -687,7 +687,7 @@ FILE_VERSION_FILTER =
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
# tag is left empty.
LAYOUT_FILE =
LAYOUT_FILE =
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
@ -697,7 +697,7 @@ LAYOUT_FILE =
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
# search path. See also \cite for info how to create references.
CITE_BIB_FILES =
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
@ -756,7 +756,7 @@ WARN_FORMAT = "$file:$line: $text"
# messages should be written. If left blank the output is written to standard
# error (stderr).
WARN_LOGFILE =
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
@ -768,7 +768,7 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = ../core/ ../main/ ../scene/
INPUT = E:/development/godot
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@ -844,7 +844,7 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE =
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
@ -860,7 +860,7 @@ EXCLUDE_SYMLINKS = NO
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
EXCLUDE_PATTERNS =
EXCLUDE_PATTERNS =
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@ -871,13 +871,13 @@ EXCLUDE_PATTERNS =
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*
EXCLUDE_SYMBOLS =
EXCLUDE_SYMBOLS =
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
# that contain example code fragments that are included (see the \include
# command).
EXAMPLE_PATH =
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
@ -897,7 +897,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
IMAGE_PATH =
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@ -914,7 +914,7 @@ IMAGE_PATH =
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
INPUT_FILTER =
INPUT_FILTER =
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis. Doxygen will compare the file name with each pattern and apply the
@ -923,7 +923,7 @@ INPUT_FILTER =
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied.
FILTER_PATTERNS =
FILTER_PATTERNS =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will also be used to filter the input files that are used for
@ -938,7 +938,7 @@ FILTER_SOURCE_FILES = NO
# *.ext= (so without naming a filter).
# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
FILTER_SOURCE_PATTERNS =
FILTER_SOURCE_PATTERNS =
# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
# is part of the input, its contents will be placed on the main page
@ -1050,7 +1050,7 @@ CLANG_ASSISTED_PARSING = NO
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_OPTIONS =
CLANG_OPTIONS =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
@ -1076,7 +1076,7 @@ COLS_IN_ALPHA_INDEX = 5
# while generating the index headers.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
IGNORE_PREFIX =
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
@ -1120,7 +1120,7 @@ HTML_FILE_EXTENSION = .html
# of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_HEADER =
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard
@ -1130,7 +1130,7 @@ HTML_HEADER =
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FOOTER =
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
@ -1142,7 +1142,7 @@ HTML_FOOTER =
# obsolete.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_STYLESHEET =
HTML_STYLESHEET =
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# cascading style sheets that are included after the standard style sheets
@ -1155,7 +1155,7 @@ HTML_STYLESHEET =
# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_STYLESHEET =
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
@ -1165,7 +1165,7 @@ HTML_EXTRA_STYLESHEET =
# files will be copied as-is; there are no commands or markers available.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_FILES =
HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
@ -1293,7 +1293,7 @@ GENERATE_HTMLHELP = NO
# written to the html output directory.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_FILE =
CHM_FILE =
# The HHC_LOCATION tag can be used to specify the location (absolute path
# including file name) of the HTML help compiler (hhc.exe). If non-empty,
@ -1301,7 +1301,7 @@ CHM_FILE =
# The file has to be specified with full path.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
HHC_LOCATION =
HHC_LOCATION =
# The GENERATE_CHI flag controls if a separate .chi index file is generated
# (YES) or that it should be included in the master .chm file (NO).
@ -1314,7 +1314,7 @@ GENERATE_CHI = NO
# and project file content.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_INDEX_ENCODING =
CHM_INDEX_ENCODING =
# The BINARY_TOC flag controls whether a binary table of contents is generated
# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
@ -1345,7 +1345,7 @@ GENERATE_QHP = NO
# the HTML output folder.
# This tag requires that the tag GENERATE_QHP is set to YES.
QCH_FILE =
QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
@ -1370,7 +1370,7 @@ QHP_VIRTUAL_FOLDER = doc
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
@ -1378,21 +1378,21 @@ QHP_CUST_FILTER_NAME =
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_ATTRS =
QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
# The QHG_LOCATION tag can be used to specify the location of Qt's
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
# generated .qhp file.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHG_LOCATION =
QHG_LOCATION =
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
# generated, together with the HTML files, they form an Eclipse help plugin. To
@ -1525,7 +1525,7 @@ MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_EXTENSIONS =
MATHJAX_EXTENSIONS =
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
# of code that will be used on startup of the MathJax code. See the MathJax site
@ -1533,7 +1533,7 @@ MATHJAX_EXTENSIONS =
# example see the documentation.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_CODEFILE =
MATHJAX_CODEFILE =
# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
# the HTML output. The underlying search engine uses javascript and DHTML and
@ -1593,7 +1593,7 @@ EXTERNAL_SEARCH = NO
# Searching" for details.
# This tag requires that the tag SEARCHENGINE is set to YES.
SEARCHENGINE_URL =
SEARCHENGINE_URL =
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
# search data is written to a file for indexing by an external tool. With the
@ -1609,7 +1609,7 @@ SEARCHDATA_FILE = searchdata.xml
# projects and redirect the results back to the right project.
# This tag requires that the tag SEARCHENGINE is set to YES.
EXTERNAL_SEARCH_ID =
EXTERNAL_SEARCH_ID =
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
# projects other than the one defined by this configuration file, but that are
@ -1619,7 +1619,7 @@ EXTERNAL_SEARCH_ID =
# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
# This tag requires that the tag SEARCHENGINE is set to YES.
EXTRA_SEARCH_MAPPINGS =
EXTRA_SEARCH_MAPPINGS =
#---------------------------------------------------------------------------
# Configuration options related to the LaTeX output
@ -1680,7 +1680,7 @@ PAPER_TYPE = a4
# If left blank no extra packages will be included.
# This tag requires that the tag GENERATE_LATEX is set to YES.
EXTRA_PACKAGES =
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
# generated LaTeX document. The header should contain everything until the first
@ -1696,7 +1696,7 @@ EXTRA_PACKAGES =
# to HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER =
LATEX_HEADER =
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
# generated LaTeX document. The footer should contain everything after the last
@ -1707,7 +1707,7 @@ LATEX_HEADER =
# Note: Only use a user-defined footer if you know what you are doing!
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_FOOTER =
LATEX_FOOTER =
# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# LaTeX style sheets that are included after the standard style sheets created
@ -1718,7 +1718,7 @@ LATEX_FOOTER =
# list).
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EXTRA_STYLESHEET =
LATEX_EXTRA_STYLESHEET =
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the LATEX_OUTPUT output
@ -1726,7 +1726,7 @@ LATEX_EXTRA_STYLESHEET =
# markers available.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EXTRA_FILES =
LATEX_EXTRA_FILES =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
@ -1826,14 +1826,14 @@ RTF_HYPERLINKS = NO
# default style sheet that doxygen normally uses.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_STYLESHEET_FILE =
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an RTF document. Syntax is
# similar to doxygen's config file. A template extensions file can be generated
# using doxygen -e rtf extensionFile.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_EXTENSIONS_FILE =
RTF_EXTENSIONS_FILE =
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
# with syntax highlighting in the RTF output.
@ -1878,7 +1878,7 @@ MAN_EXTENSION = .3
# MAN_EXTENSION with the initial . removed.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_SUBDIR =
MAN_SUBDIR =
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
# will generate one additional man file for each entity documented in the real
@ -1991,7 +1991,7 @@ PERLMOD_PRETTY = YES
# overwrite each other's variables.
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
PERLMOD_MAKEVAR_PREFIX =
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
@ -2032,7 +2032,7 @@ SEARCH_INCLUDES = YES
# preprocessor.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
INCLUDE_PATH =
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
@ -2040,7 +2040,7 @@ INCLUDE_PATH =
# used.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
INCLUDE_FILE_PATTERNS =
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that are
# defined before the preprocessor is started (similar to the -D option of e.g.
@ -2050,7 +2050,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED =
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@ -2059,7 +2059,7 @@ PREDEFINED =
# definition found in the source code.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_AS_DEFINED =
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have
@ -2088,13 +2088,13 @@ SKIP_FUNCTION_MACROS = YES
# the path). If a tag file is not located in the directory in which doxygen is
# run, you must also specify the path to the tagfile here.
TAGFILES =
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
# tag file that is based on the input files it reads. See section "Linking to
# external documentation" for more information about the usage of tag files.
GENERATE_TAGFILE =
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
# the class index. If set to NO, only the inherited external classes will be
@ -2143,14 +2143,14 @@ CLASS_DIAGRAMS = YES
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
MSCGEN_PATH =
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
# If left empty dia is assumed to be found in the default search path.
DIA_PATH =
DIA_PATH =
# If set to YES the inheritance and collaboration graphs will hide inheritance
# and usage relations if the target is undocumented or is not a class.
@ -2199,7 +2199,7 @@ DOT_FONTSIZE = 10
# the path where dot can find it using this tag.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTPATH =
DOT_FONTPATH =
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
# each documented class showing the direct and indirect inheritance relations.
@ -2337,26 +2337,26 @@ INTERACTIVE_SVG = NO
# found. If left blank, it is assumed the dot tool can be found in the path.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_PATH =
DOT_PATH =
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the \dotfile
# command).
# This tag requires that the tag HAVE_DOT is set to YES.
DOTFILE_DIRS =
DOTFILE_DIRS =
# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the \mscfile
# command).
MSCFILE_DIRS =
MSCFILE_DIRS =
# The DIAFILE_DIRS tag can be used to specify one or more directories that
# contain dia files that are included in the documentation (see the \diafile
# command).
DIAFILE_DIRS =
DIAFILE_DIRS =
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
# path where java can find the plantuml.jar file. If left blank, it is assumed
@ -2364,12 +2364,12 @@ DIAFILE_DIRS =
# generate a warning when it encounters a \startuml command in this case and
# will not generate output for the diagram.
PLANTUML_JAR_PATH =
PLANTUML_JAR_PATH =
# When using plantuml, the specified paths are searched for files specified by
# the !include statement in a plantuml block.
PLANTUML_INCLUDE_PATH =
PLANTUML_INCLUDE_PATH =
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
# that will be shown in the graph. If the number of nodes in a graph becomes

27
LICENSE.md Normal file
View File

@ -0,0 +1,27 @@
GODOT ENGINE
http://www.godotengine.org
**********************************************************************
Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.
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.
**********************************************************************

View File

@ -1,20 +0,0 @@
Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
Copyright (c) 2014-2021 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.

View File

@ -1,5 +0,0 @@
Godot Engine Logo
Copyright (c) 2017 Andrea Calabró
This work is licensed under a Creative Commons Attribution 4.0 International
License (CC-BY-4.0 International) <https://creativecommons.org/licenses/by/4.0/>.

View File

@ -1,78 +1,26 @@
# Godot Engine
![GODOT](/logo.png)
<p align="center">
<a href="https://godotengine.org">
<img src="logo_outlined.svg" width="400" alt="Godot Engine logo">
</a>
</p>
### The Engine
## 2D and 3D cross-platform game engine
Godot is a fully featured, open source, MIT licensed, game engine. It focuses on having great tools, and a visual oriented workflow that can export to PC, Mobile and Web platforms with no hassle.
The editor, language and APIs are feature rich, yet simple to learn, allowing you to become productive in a matter of hours.
**[Godot Engine](https://godotengine.org) is a feature-packed, cross-platform
game engine to create 2D and 3D games from a unified interface.** It provides a
comprehensive set of common tools, so that users can focus on making games
without having to reinvent the wheel. Games can be exported in one click to a
number of platforms, including the major desktop platforms (Linux, macOS,
Windows), mobile platforms (Android, iOS), as well as Web-based platforms
(HTML5) and
[consoles](https://docs.godotengine.org/en/latest/tutorials/platform/consoles.html).
### About
## Free, open source and community-driven
Godot has been developed by Juan Linietsky and Ariel Manzur for several years, and was born as an in-house engine, used to publish several work-for-hire titles.
Development is sponsored by OKAM Studio (http://www.okamstudio.com).
Godot is completely free and open source under the very permissive MIT license.
No strings attached, no royalties, nothing. The users' games are theirs, down
to the last line of engine code. Godot's development is fully independent and
community-driven, empowering users to help shape their engine to match their
expectations. It is supported by the [Software Freedom Conservancy](https://sfconservancy.org/)
not-for-profit.
### Documentation
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.
Documentation has been moved to the [GitHub Wiki](https://github.com/okamstudio/godot/wiki).
![Screenshot of a 3D scene in Godot Engine](https://raw.githubusercontent.com/godotengine/godot-design/master/screenshots/editor_tps_demo_1920x1080.jpg)
### Binary Downloads, Community, etc.
## Getting the engine
Binary downloads, community, etc. can be found in Godot homepage:
### Binary downloads
http://www.godotengine.org
Official binaries for the Godot editor and the export templates can be found
[on the homepage](https://godotengine.org/download).
### Compiling from Source
### Compiling from source
[See the official docs](https://docs.godotengine.org/en/latest/development/compiling/)
for compilation instructions for every supported platform.
## Community and contributing
Godot is not only an engine but an ever-growing community of users and engine
developers. The main community channels are listed [on the homepage](https://godotengine.org/community).
To get in touch with the engine developers, the best way is to join the
[Godot Contributors Chat](https://chat.godotengine.org).
To get started contributing to the project, see the [contributing guide](CONTRIBUTING.md).
## Documentation and demos
The official documentation is hosted on [ReadTheDocs](https://docs.godotengine.org).
It is maintained by the Godot community in its own [GitHub repository](https://github.com/godotengine/godot-docs).
The [class reference](https://docs.godotengine.org/en/latest/classes/)
is also accessible from the Godot editor.
The official demos are maintained in their own [GitHub repository](https://github.com/godotengine/godot-demo-projects)
as well.
There are also a number of other
[learning resources](https://docs.godotengine.org/en/latest/community/tutorials.html)
provided by the community, such as text and video tutorials, demos, etc.
Consult the [community channels](https://godotengine.org/community)
for more information.
[![Actions Build Status](https://github.com/godotengine/godot/workflows/Godot/badge.svg?branch=master)](https://github.com/godotengine/godot/actions)
[![Code Triagers Badge](https://www.codetriage.com/godotengine/godot/badges/users.svg)](https://www.codetriage.com/godotengine/godot)
[![Translate on Weblate](https://hosted.weblate.org/widgets/godot-engine/-/godot/svg-badge.svg)](https://hosted.weblate.org/engage/godot-engine/?utm_source=widget)
[![Total alerts on LGTM](https://img.shields.io/lgtm/alerts/g/godotengine/godot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/godotengine/godot/alerts)
[![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.com/godotengine/godot)](https://www.tickgit.com/browse?repo=github.com/godotengine/godot)
Compilation instructions for every platform can be found in the Wiki:
https://github.com/okamstudio/godot/wiki/advanced

File diff suppressed because it is too large Load Diff

4
bin/SCsub Normal file
View File

@ -0,0 +1,4 @@
Import('env')
Export('env')
SConscript('tests/SCsub');

14
bin/tests/SCsub Normal file
View File

@ -0,0 +1,14 @@
Import('env')
env.tests_sources=[]
env.add_source_files(env.tests_sources,"*.cpp")
Export('env')
#SConscript('math/SCsub');
lib = env.Library("tests",env.tests_sources)
env.Prepend(LIBS=[lib])

View File

@ -0,0 +1,107 @@
/*************************************************************************/
/* test_containers.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_containers.h"
#include "dvector.h"
#include "set.h"
#include "print_string.h"
#include "math_funcs.h"
#include "servers/visual/default_mouse_cursor.xpm"
#include "variant.h"
#include "list.h"
#include "image.h"
namespace TestContainers {
MainLoop * test() {
/*
HashMap<int,int> int_map;
for (int i=0;i<68000;i++) {
int num=(int)Math::random(0,1024);
int_map[i]=num;
}
*/
{
// static const int size = 16;
Image img;
img.create(default_mouse_cursor_xpm);
{
for (int i=0; i<8; i++) {
Image mipmap;
//img.make_mipmap(mipmap);
img = mipmap;
if (img.get_width() <= 4) break;
};
};
};
#if 0
Set<int> set;
print_line("Begin Insert");
for (int i=0;i<1100;i++) {
int num=i;//(int)Math::random(0,1024);
// print_line("inserting "+itos(num));
set.insert( num );
}
/*
for (int i=0;i<400;i++) {
int num=(int)Math::random(0,1024);
set.erase(num);
}
*/
//set.print_tree();
for(Set<int>::Element *I=set.front();I;I=I->next()) {
print_line("inserted "+itos(I->get())+" prev is "+itos(I->prev()?I->prev()->get():-100));
}
print_line("depth is "+itos(set.calculate_depth()));
print_line("Insert Success");
#endif
return NULL;
}
}

View File

@ -0,0 +1,43 @@
/*************************************************************************/
/* test_containers.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 TEST_CONTAINERS_H
#define TEST_CONTAINERS_H
#include "os/main_loop.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
namespace TestContainers {
MainLoop * test();
}
#endif

217
bin/tests/test_detailer.cpp Normal file
View File

@ -0,0 +1,217 @@
/*************************************************************************/
/* test_detailer.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_detailer.h"
#include "servers/visual_server.h"
#include "os/main_loop.h"
#include "math_funcs.h"
#include "print_string.h"
#include "geometry.h"
#include "quick_hull.h"
namespace TestMultiMesh {
class TestMainLoop : public MainLoop {
RID instance;
RID camera;
RID viewport;
RID light;
RID mesh;
RID scenario;
#define MULTIMESH_COUNT 1500
float ofs_x,ofs_y;
bool quit;
public:
virtual void _update_qh() {
VisualServer *vs=VisualServer::get_singleton();
Vector<Vector3> vts;
/*
static const int s = 20;
for(int i=0;i<s;i++) {
Matrix3 rot(Vector3(0,1,0),i*Math_PI/s);
for(int j=0;j<s;j++) {
Vector3 v;
v.x=Math::sin(j*Math_PI*2/s);
v.y=Math::cos(j*Math_PI*2/s);
vts.push_back( rot.xform(v*2 ) );
}
}*/
/*
Math::seed(0);
for(int i=0;i<50;i++) {
vts.push_back( Vector3(Math::randf()*2-1.0,Math::randf()*2-1.0,Math::randf()*2-1.0).normalized()*2);
}*/
/*
vts.push_back(Vector3(0,0,1));
vts.push_back(Vector3(0,0,-1));
vts.push_back(Vector3(0,1,0));
vts.push_back(Vector3(0,-1,0));
vts.push_back(Vector3(1,0,0));
vts.push_back(Vector3(-1,0,0));*/
/*
vts.push_back(Vector3(1,1,1));
vts.push_back(Vector3(1,-1,1));
vts.push_back(Vector3(-1,1,1));
vts.push_back(Vector3(-1,-1,1));
vts.push_back(Vector3(1,1,-1));
vts.push_back(Vector3(1,-1,-1));
vts.push_back(Vector3(-1,1,-1));
vts.push_back(Vector3(-1,-1,-1));
*/
DVector<Plane> convex_planes = Geometry::build_cylinder_planes(0.5,0.7,4,Vector3::AXIS_Z);
Geometry::MeshData convex_data = Geometry::build_convex_mesh(convex_planes);
vts=convex_data.vertices;
Geometry::MeshData md;
Error err = QuickHull::build(vts,md);
print_line("ERR: "+itos(err));
vs->mesh_remove_surface(mesh,0);
vs->mesh_add_surface_from_mesh_data(mesh,md);
//vs->scenario_set_debug(scenario,VS::SCENARIO_DEBUG_WIREFRAME);
/*
RID sm = vs->shader_create();
//vs->shader_set_fragment_code(sm,"OUT_ALPHA=mod(TIME,1);");
//vs->shader_set_vertex_code(sm,"OUT_VERTEX=IN_VERTEX*mod(TIME,1);");
vs->shader_set_fragment_code(sm,"OUT_DIFFUSE=vec3(1,0,1);OUT_GLOW=abs(sin(TIME));");
RID tcmat = vs->mesh_surface_get_material(test_cube,0);
vs->material_set_shader(tcmat,sm);
*/
}
virtual void input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
ofs_x+=p_event.mouse_motion.relative_y/200.0;
ofs_y+=p_event.mouse_motion.relative_x/200.0;
}
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index==1) {
QuickHull::debug_stop_after++;
_update_qh();
}
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index==2) {
if (QuickHull::debug_stop_after>0)
QuickHull::debug_stop_after--;
_update_qh();
}
}
virtual void request_quit() {
quit=true;
}
virtual void init() {
VisualServer *vs=VisualServer::get_singleton();
mesh = vs->mesh_create();
scenario = vs->scenario_create();
QuickHull::debug_stop_after=0;
_update_qh();
instance = vs->instance_create2(mesh,scenario);
camera = vs->camera_create();
vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create();
vs->viewport_attach_camera( viewport, camera );
vs->viewport_attach_to_screen(viewport);
vs->viewport_set_scenario( viewport, scenario );
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,0,2 ) ) );
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.3,0.3,0.3) );
light = vs->instance_create2( lightaux,scenario );
vs->instance_set_transform(light,Transform(Matrix3(Vector3(0.1,0.4,0.7).normalized(),0.9)));
ofs_x=0;
ofs_y=0;
quit=false;
}
virtual bool idle(float p_time) {
return false;
}
virtual bool iteration(float p_time) {
VisualServer *vs=VisualServer::get_singleton();
Transform tr_camera;
tr_camera.rotate( Vector3(0,1,0), ofs_y );
tr_camera.rotate( Vector3(1,0,0),ofs_x );
tr_camera.translate(0,0,10);
vs->camera_set_transform( camera, tr_camera );
return quit;
}
virtual void finish() {
}
};
MainLoop* test() {
return memnew(TestMainLoop);
}
}

44
bin/tests/test_detailer.h Normal file
View File

@ -0,0 +1,44 @@
/*************************************************************************/
/* test_detailer.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 TEST_MULTIMESH_H
#define TEST_MULTIMESH_H
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#include "os/main_loop.h"
namespace TestMultiMesh {
MainLoop* test();
}
#endif

1042
bin/tests/test_gdscript.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,11 +26,10 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEST_GDSCRIPT_H
#define TEST_GDSCRIPT_H
#include "core/os/main_loop.h"
#include "os/main_loop.h"
namespace TestGDScript {
@ -42,7 +40,8 @@ enum TestType {
TEST_BYTECODE,
};
MainLoop *test(TestType p_type);
} // namespace TestGDScript
MainLoop* test(TestType p_type);
}
#endif // TEST_GDSCRIPT_H

399
bin/tests/test_gui.cpp Normal file
View File

@ -0,0 +1,399 @@
/*************************************************************************/
/* test_gui.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 _3D_DISABLED
#include "test_gui.h"
#include "scene/main/scene_main_loop.h"
#include "os/os.h"
#include "scene/gui/control.h"
#include "scene/gui/button.h"
#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/scroll_bar.h"
#include "scene/gui/popup_menu.h"
#include "scene/gui/option_button.h"
#include "scene/gui/spin_box.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/progress_bar.h"
#include "scene/gui/panel.h"
#include "scene/gui/tab_container.h"
#include "scene/gui/tree.h"
#include "scene/gui/rich_text_label.h"
#include "scene/gui/texture_frame.h"
#include "io/image_loader.h"
#include "print_string.h"
#include "scene/2d/sprite.h"
#include "scene/main/viewport.h"
#include "scene/3d/camera.h"
#include "scene/3d/test_cube.h"
namespace TestGUI {
class TestMainLoop : public SceneTree {
Control *control;
public:
virtual void request_quit() {
quit();
}
virtual void init() {
SceneTree::init();
#if 0
Viewport *vp = memnew( Viewport );
vp->set_world( Ref<World>( memnew( World )));
get_root()->add_child(vp);
vp->set_rect(Rect2(0,0,256,256));
vp->set_as_render_target(true);
vp->set_render_target_update_mode(Viewport::RENDER_TARGET_UPDATE_ALWAYS);
Camera *camera = memnew( Camera );
vp->add_child(camera);
camera->make_current();
TestCube *testcube = memnew( TestCube );
vp->add_child(testcube);
testcube->set_transform(Transform( Matrix3().rotated(Vector3(0,1,0),Math_PI*0.25), Vector3(0,0,-8)));
Sprite *sp = memnew( Sprite );
sp->set_texture( vp->get_render_target_texture() );
// sp->set_texture( ResourceLoader::load("res://ball.png") );
sp->set_pos(Point2(300,300));
get_root()->add_child(sp);
return;
#endif
Panel * frame = memnew( Panel );
frame->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END );
frame->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_END );
frame->set_end( Point2(0,0) );
get_root()->add_child( frame );
Label *label = memnew( Label );
label->set_pos( Point2( 80,90 ) );
label->set_size( Point2( 170,80 ) );
label->set_align( Label::ALIGN_FILL );
//label->set_text("There");
label->set_text("There was once upon a time a beautiful unicorn that loved to play with little girls...");
frame->add_child(label);
Button *button = memnew( Button );
button->set_pos( Point2( 20,20 ) );
button->set_size( Point2( 1,1 ) );
button->set_text("This is a biggie button");
frame->add_child( button );
#if 0
Sprite *tf = memnew( Sprite );
frame->add_child(tf);
Image img;
ImageLoader::load_image("LarvoClub.png",&img);
img.resize(512,512);
img.generate_mipmaps();
img.compress(Image::COMPRESS_PVRTC4);
Ref<ImageTexture> tt = memnew( ImageTexture );
tt->create_from_image(img);
tf->set_texture(tt);
tf->set_pos(Point2(50,50));
//tf->set_scale(Point2(0.3,0.3));
return;
#endif
Tree * tree = memnew( Tree );
tree->set_columns(2);
tree->set_pos( Point2( 230,210 ) );
tree->set_size( Point2( 150,250 ) );
TreeItem *item = tree->create_item();
item->set_editable(0,true);
item->set_text(0,"root");
item = tree->create_item( tree->get_root() );
item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
item->set_editable(0,true);
item->set_text(0,"check");
item->set_cell_mode(1, TreeItem::CELL_MODE_CHECK);
item->set_editable(1,true);
item->set_text(1,"check2");
item = tree->create_item( tree->get_root() );
item->set_cell_mode(0, TreeItem::CELL_MODE_RANGE);
item->set_editable(0,true);
item->set_range_config(0,0,20,0.1);
item->set_range(0,2);
item->add_button(0,Theme::get_default()->get_icon("folder","FileDialog"));
item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
item->set_editable(1,true);
item->set_range_config(1,0,20,0.1);
item->set_range(1,3);
item = tree->create_item( tree->get_root() );
item->set_cell_mode(0, TreeItem::CELL_MODE_RANGE);
item->set_editable(0,true);
item->set_text(0,"Have,Many,Several,Options!");
item->set_range(0,2);
item = tree->create_item( item );
item->set_editable(0,true);
item->set_text(0,"Gershwin!");
frame->add_child(tree);
//control = memnew( Control );
//root->add_child( control );
LineEdit *line_edit = memnew( LineEdit );
line_edit->set_pos( Point2( 30,190 ) );
line_edit->set_size( Point2( 180,1 ) );
frame->add_child(line_edit);
HScrollBar *hscroll = memnew( HScrollBar );
hscroll->set_pos( Point2( 30,290 ) );
hscroll->set_size( Point2( 180,1 ) );
hscroll->set_max(10);
hscroll->set_page(4);
frame->add_child(hscroll);
SpinBox *spin = memnew( SpinBox );
spin->set_pos( Point2( 30,260 ) );
spin->set_size( Point2( 120,1 ) );
frame->add_child(spin);
hscroll->share(spin);
ProgressBar *progress = memnew( ProgressBar );
progress->set_pos( Point2( 30,330 ) );
progress->set_size( Point2( 120,1 ) );
frame->add_child(progress);
hscroll->share(progress);
MenuButton *menu_button = memnew( MenuButton );
menu_button->set_text("I'm a menu!");
menu_button->set_pos( Point2( 30,380 ) );
menu_button->set_size( Point2( 1,1 ) );
frame->add_child(menu_button);
PopupMenu *popup = menu_button->get_popup();
popup->add_item("Hello, testing");
popup->add_item("My Dearest");
popup->add_separator();
popup->add_item("Popup");
popup->add_check_item("Check Popup");
popup->set_item_checked(4,true);
OptionButton *options = memnew( OptionButton );
options->add_item("Hello, testing");
options->add_item("My Dearest");
options->set_pos( Point2( 230,180 ) );
options->set_size( Point2( 1,1 ) );
frame->add_child(options);
/*
Tree * tree = memnew( Tree );
tree->set_columns(2);
tree->set_pos( Point2( 230,210 ) );
tree->set_size( Point2( 150,250 ) );
TreeItem *item = tree->create_item();
item->set_editable(0,true);
item->set_text(0,"root");
item = tree->create_item( tree->get_root() );
item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
item->set_editable(0,true);
item->set_text(0,"check");
item = tree->create_item( tree->get_root() );
item->set_cell_mode(0, TreeItem::CELL_MODE_RANGE);
item->set_editable(0,true);
item->set_range_config(0,0,20,0.1);
item->set_range(0,2);
item->add_button(0,Theme::get_default()->get_icon("folder","FileDialog"));
item = tree->create_item( tree->get_root() );
item->set_cell_mode(0, TreeItem::CELL_MODE_RANGE);
item->set_editable(0,true);
item->set_text(0,"Have,Many,Several,Options!");
item->set_range(0,2);
frame->add_child(tree);
*/
RichTextLabel *richtext = memnew( RichTextLabel );
richtext->set_pos( Point2( 600,210 ) );
richtext->set_size( Point2( 180,250 ) );
richtext->set_anchor_and_margin(MARGIN_RIGHT,Control::ANCHOR_END,20);
frame->add_child(richtext);
richtext->add_text("Hello, My Friends!\n\nWelcome to the amazing world of ");
richtext->add_newline();
richtext->add_newline();
richtext->push_color(Color(1,0.5,0.5));
richtext->add_text("leprechauns");
richtext->pop();
richtext->add_text(" and ");
richtext->push_color(Color(0,1.0,0.5));
richtext->add_text("faeries.\n");
richtext->pop();
richtext->add_text("In this new episode, we will attemp to ");
richtext->push_font(richtext->get_font("mono_font","Fonts"));
richtext->push_color(Color(0.7,0.5,1.0));
richtext->add_text("deliver something nice");
richtext->pop();
richtext->pop();
richtext->add_text(" to all the viewers! Unfortunately, I need to ");
richtext->push_underline();
richtext->add_text("keep writing a lot of text");
richtext->pop();
richtext->add_text(" so the label control overflows and the scrollbar appears.\n");
//richtext->push_indent(1);
//richtext->add_text("By the way, testing indent levels! Yohohoho! Everything should appear to the right sightly here!\n");
//richtext->pop();
richtext->push_meta("http://www.scrollingcapabilities.xz");
richtext->add_text("This allows to test for the scrolling capabilities ");
richtext->pop();
richtext->add_text("of the rich text label for huge text (not like this text will really be huge but, you know).\nAs long as it is so long that it will work nicely for a test/demo, then it's welcomed in my book...\nChanging subject, the day is cloudy today and I'm wondering if I'll get che chance to travel somewhere nice. Sometimes, watching the clouds from satellite images may give a nice insight about how pressure zones in our planet work, althogh it also makes it pretty obvious to see why most weather forecasts get it wrong so often.\nClouds are so difficult to predict!\nBut it's pretty cool how our civilization has adapted to having water falling from the sky each time it rains...");
//richtext->add_text("Hello!\nGorgeous..");
//richtext->push_meta("http://www.scrollingcapabilities.xz");
///richtext->add_text("Hello!\n");
//richtext->pop();
richtext->set_anchor(MARGIN_RIGHT,Control::ANCHOR_END);
TabContainer * tabc = memnew( TabContainer );
Control *ctl= memnew( Control );
ctl->set_name("tab 1");
tabc->add_child(ctl);
ctl= memnew( Control );
ctl->set_name("tab 2");
tabc->add_child(ctl);
label = memnew( Label );
label->set_text("Some Label");
label->set_pos( Point2(20,20) );
ctl->add_child(label);;
ctl= memnew( Control );
ctl->set_name("tab 3");
button = memnew( Button );
button->set_text("Some Button");
button->set_pos( Point2(30,50) );
ctl->add_child(button);;
tabc->add_child(ctl);
frame->add_child(tabc);
tabc->set_pos( Point2( 400,210 ) );
tabc->set_size( Point2( 180,250 ) );
Ref<ImageTexture> text = memnew( ImageTexture );
text->load("test_data/concave.png");
Sprite* sprite = memnew(Sprite);
sprite->set_texture(text);
sprite->set_pos(Point2(300, 300));
frame->add_child(sprite);
sprite->show();
Sprite* sprite2 = memnew(Sprite);
sprite->set_texture(text);
sprite->add_child(sprite2);
sprite2->set_pos(Point2(50, 50));
sprite2->show();
}
};
MainLoop* test() {
return memnew( TestMainLoop );
}
}
#endif

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,15 +26,19 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEST_GUI_H
#define TEST_GUI_H
#include "core/os/main_loop.h"
#include "os/main_loop.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
namespace TestGUI {
MainLoop *test();
MainLoop* test();
}
#endif

77
bin/tests/test_image.cpp Normal file
View File

@ -0,0 +1,77 @@
/*************************************************************************/
/* test_image.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_image.h"
#include "os/main_loop.h"
#include "math_funcs.h"
#include "print_string.h"
#include "io/image_loader.h"
namespace TestImage {
class TestMainLoop : public MainLoop {
bool quit;
public:
virtual void input_event(const InputEvent& p_event) {
}
virtual void init() {
quit=false;
}
virtual bool iteration(float p_time) {
return quit;
}
virtual bool idle(float p_time) {
return quit;
}
virtual void finish() {
}
};
MainLoop* test() {
Image img;
ImageLoader::load_image("as1.png",&img);
img.resize(512,512);
return memnew( TestMainLoop );
}
}

44
bin/tests/test_image.h Normal file
View File

@ -0,0 +1,44 @@
/*************************************************************************/
/* test_image.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 TEST_IMAGE_H
#define TEST_IMAGE_H
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#include "os/main_loop.h"
namespace TestImage {
MainLoop* test();
}
#endif

208
bin/tests/test_io.cpp Normal file
View File

@ -0,0 +1,208 @@
/*************************************************************************/
/* test_io.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_io.h"
#ifdef MINIZIP_ENABLED
#include "os/main_loop.h"
#include "os/os.h"
#include "scene/resources/texture.h"
#include "print_string.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
#include "os/dir_access.h"
#include "core/globals.h"
#include "io/file_access_memory.h"
namespace TestIO {
class TestMainLoop : public MainLoop {
bool quit;
public:
virtual void input_event(const InputEvent& p_event) {
}
virtual bool idle(float p_time) {
return false;
}
virtual void request_quit() {
quit=true;
}
virtual void init() {
quit=true;
}
virtual bool iteration(float p_time) {
return quit;
}
virtual void finish() {
}
};
MainLoop* test() {
print_line("this is test io");
DirAccess* da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
da->change_dir(".");
print_line("Opening current dir "+ da->get_current_dir());
String entry;
da->list_dir_begin();
while ( (entry = da->get_next()) != "") {
print_line("entry "+entry+" is dir: " + Variant(da->current_is_dir()));
};
da->list_dir_end();
RES texture = ResourceLoader::load("test_data/rock.png");
ERR_FAIL_COND_V(texture.is_null(), NULL);
ResourceSaver::save("test_data/rock.xml",texture);
print_line("localize paths");
print_line(Globals::get_singleton()->localize_path("algo.xml"));
print_line(Globals::get_singleton()->localize_path("c:\\windows\\algo.xml"));
print_line(Globals::get_singleton()->localize_path(Globals::get_singleton()->get_resource_path()+"/something/something.xml"));
print_line(Globals::get_singleton()->localize_path("somedir/algo.xml"));
{
FileAccess* z = FileAccess::open("test_data/archive.zip", FileAccess::READ);
int len = z->get_len();
Vector<uint8_t> zip;
zip.resize(len);
z->get_buffer(&zip[0], len);
z->close();
memdelete(z);
FileAccessMemory::register_file("a_package", zip);
FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_FILESYSTEM);
FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_USERDATA);
print_line("archive test");
#if 0
Archive arch;
Archive::get_singleton()->add_package("a_package");
FileAccessArchive f;
print_line("opening for read");
f._open("file.txt", FileAccess::READ);
int pos = f.get_pos();
printf("file has %i bytes, initial pos %i\n", (int)f.get_len(), pos);
do {
printf("%c", f.get_8());
} while (!f.eof_reached());
print_line("opening for stored seek");
f.open("seek.bin", FileAccess::READ);
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
f.seek(128);
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
print_line("opening for deflated seek");
f.open("seek_deflated.bin", FileAccess::READ);
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
f.seek(128);
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
f.seek(256);
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
f.seek(4);
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
pos = f.get_pos();
printf("byte at pos %i is %i\n", pos, (int)f.get_8());
f.close();
DirAccessArchive d;
String dir = "../blah1/blah2/blahask/../blah3/.//blah4/";
printf("changing dir to %s\n", dir.utf8().get_data());
d.change_dir(dir);
printf("current dir is %s\n", d.get_current_dir().utf8().get_data());
FileAccessMemory::cleanup();
#endif
};
print_line("test done");
return memnew( TestMainLoop );
}
}
#else
namespace TestIO {
MainLoop* test() {
return NULL;
}
}
#endif

44
bin/tests/test_io.h Normal file
View File

@ -0,0 +1,44 @@
/*************************************************************************/
/* test_io.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 TEST_IO_H
#define TEST_IO_H
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#include "os/main_loop.h"
namespace TestIO {
MainLoop* test();
}
#endif

197
bin/tests/test_main.cpp Normal file
View File

@ -0,0 +1,197 @@
/*************************************************************************/
/* test_main.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "list.h"
#include "os/main_loop.h"
#ifdef DEBUG_ENABLED
#include "test_string.h"
#include "test_containers.h"
#include "test_math.h"
#include "test_gui.h"
#include "test_render.h"
#include "test_sound.h"
#include "test_misc.h"
#include "test_physics.h"
#include "test_physics_2d.h"
#include "test_python.h"
#include "test_io.h"
#include "test_particles.h"
#include "test_detailer.h"
#include "test_shader_lang.h"
#include "test_gdscript.h"
#include "test_image.h"
const char ** tests_get_names() {
static const char* test_names[]={
"string",
"containers",
"math",
"render",
"particles",
"multimesh",
"gui",
"io",
"shaderlang",
NULL
};
return test_names;
}
MainLoop* test_main(String p_test,const List<String>& p_args) {
if (p_test=="string") {
return TestString::test();
}
if (p_test=="containers") {
return TestContainers::test();
}
if (p_test=="math") {
return TestMath::test();
}
if (p_test=="physics") {
return TestPhysics::test();
}
if (p_test=="physics_2d") {
return TestPhysics2D::test();
}
if (p_test=="misc") {
return TestMisc::test();
}
if (p_test=="render") {
return TestRender::test();
}
#ifndef _3D_DISABLED
if (p_test=="gui") {
return TestGUI::test();
}
#endif
if (p_test=="sound") {
return TestSound::test();
}
if (p_test=="io") {
return TestIO::test();
}
if (p_test=="particles") {
return TestParticles::test();
}
if (p_test=="multimesh") {
return TestMultiMesh::test();
}
if (p_test=="shaderlang") {
return TestShaderLang::test();
}
if (p_test=="gd_tokenizer") {
return TestGDScript::test(TestGDScript::TEST_TOKENIZER);
}
if (p_test=="gd_parser") {
return TestGDScript::test(TestGDScript::TEST_PARSER);
}
if (p_test=="gd_compiler") {
return TestGDScript::test(TestGDScript::TEST_COMPILER);
}
if (p_test=="gd_bytecode") {
return TestGDScript::test(TestGDScript::TEST_BYTECODE);
}
if (p_test=="image") {
return TestImage::test();
}
if (p_test=="detailer") {
return TestMultiMesh::test();
}
#ifdef PYTHON_ENABLED
if (p_test=="python") {
return TestPython::test();
}
#endif
return NULL;
}
#else
const char ** tests_get_names() {
static const char* test_names[]={
NULL
};
return test_names;
}
MainLoop* test_main(String p_test,const List<String>& p_args) {
return NULL;
}
#endif

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,15 +26,16 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEST_MAIN_H
#define TEST_MAIN_H
#include "core/list.h"
#include "core/os/main_loop.h"
#include "core/ustring.h"
#include "ustring.h"
#include "list.h"
const char ** tests_get_names();
MainLoop* test_main(String p_test,const List<String>& p_args);
#endif
const char **tests_get_names();
MainLoop *test_main(String p_test, const List<String> &p_args);
#endif // TEST_MAIN_H

301
bin/tests/test_math.cpp Normal file
View File

@ -0,0 +1,301 @@
/*************************************************************************/
/* test_math.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_math.h"
#include "ustring.h"
#include "print_string.h"
#include "transform.h"
#include "matrix3.h"
#include "math_funcs.h"
#include "camera_matrix.h"
#include "scene/main/node.h"
#include "variant.h"
#include "servers/visual/shader_language.h"
#include "os/keyboard.h"
#include "scene/resources/texture.h"
#include "vmap.h"
#include "os/os.h"
namespace TestMath {
void test_vec(Plane p_vec) {
CameraMatrix cm;
cm.set_perspective(45,1,0,100);
Plane v0=cm.xform4(p_vec);
print_line("out: "+v0);
v0.normal.z = (v0.d/100.0 *2.0-1.0) * v0.d;
print_line("out_F: "+v0);
/*v0: 0, 0, -0.1, 0.1
v1: 0, 0, 0, 0.1
fix: 0, 0, 0, 0.1
v0: 0, 0, 1.302803, 1.5
v1: 0, 0, 1.401401, 1.5
fix: 0, 0, 1.401401, 1.5
v0: 0, 0, 25.851850, 26
v1: 0, 0, 25.925926, 26
fix: 0, 0, 25.925924, 26
v0: 0, 0, 49.899902, 50
v1: 0, 0, 49.949947, 50
fix: 0, 0, 49.949951, 50
v0: 0, 0, 100, 100
v1: 0, 0, 100, 100
fix: 0, 0, 100, 100
*/
}
MainLoop* test() {
{
// print_line("NUM: "+itos(237641278346127));
print_line("NUM: "+itos(-128));
return NULL;
}
{
Vector3 v(1,2,3);
v.normalize();
float a=0.3;
//Quat q(v,a);
Matrix3 m(v,a);
Vector3 v2(7,3,1);
v2.normalize();
float a2=0.8;
//Quat q(v,a);
Matrix3 m2(v2,a2);
Quat q=m;
Quat q2=m2;
Matrix3 m3 = m.inverse() * m2;
Quat q3 = (q.inverse() * q2);//.normalized();
print_line(Quat(m3));
print_line(q3);
print_line("before v: "+v+" a: "+rtos(a));
q.get_axis_and_angle(v,a);
print_line("after v: "+v+" a: "+rtos(a));
}
return NULL;
String ret;
List<String> args;
args.push_back("-l");
Error err = OS::get_singleton()->execute("/bin/ls",args,true,NULL,&ret);
print_line("error: "+itos(err));
print_line(ret);
return NULL;
Matrix3 m3;
m3.rotate(Vector3(1,0,0),0.2);
m3.rotate(Vector3(0,1,0),1.77);
m3.rotate(Vector3(0,0,1),212);
Matrix3 m32;
m32.set_euler(m3.get_euler());
print_line("ELEULEEEEEEEEEEEEEEEEEER: "+m3.get_euler()+" vs "+m32.get_euler());
return NULL;
{
Dictionary d;
d["momo"]=1;
Dictionary b=d;
b["44"]=4;
}
return NULL;
print_line("inters: "+rtos(Geometry::segment_intersects_circle(Vector2(-5,0),Vector2(-2,0),Vector2(),1.0)));
print_line("cross: "+Vector3(1,2,3).cross(Vector3(4,5,7)));
print_line("dot: "+rtos(Vector3(1,2,3).dot(Vector3(4,5,7))));
print_line("abs: "+Vector3(-1,2,-3).abs());
print_line("distance_to: "+rtos(Vector3(1,2,3).distance_to(Vector3(4,5,7))));
print_line("distance_squared_to: "+rtos(Vector3(1,2,3).distance_squared_to(Vector3(4,5,7))));
print_line("plus: "+(Vector3(1,2,3)+Vector3(Vector3(4,5,7))));
print_line("minus: "+(Vector3(1,2,3)-Vector3(Vector3(4,5,7))));
print_line("mul: "+(Vector3(1,2,3)*Vector3(Vector3(4,5,7))));
print_line("div: "+(Vector3(1,2,3)/Vector3(Vector3(4,5,7))));
print_line("mul scalar: "+(Vector3(1,2,3)*2));
print_line("premul scalar: "+(2*Vector3(1,2,3)));
print_line("div scalar: "+(Vector3(1,2,3)/3.0));
print_line("length: "+rtos(Vector3(1,2,3).length()));
print_line("length squared: "+rtos(Vector3(1,2,3).length_squared()));
print_line("normalized: "+Vector3(1,2,3).normalized());
print_line("inverse: "+Vector3(1,2,3).inverse());
{
Vector3 v(4,5,7);
v.normalize();
print_line("normalize: "+v);
}
{
Vector3 v(4,5,7);
v+=Vector3(1,2,3);
print_line("+=: "+v);
}
{
Vector3 v(4,5,7);
v-=Vector3(1,2,3);
print_line("-=: "+v);
}
{
Vector3 v(4,5,7);
v*=Vector3(1,2,3);
print_line("*=: "+v);
}
{
Vector3 v(4,5,7);
v/=Vector3(1,2,3);
print_line("/=: "+v);
}
{
Vector3 v(4,5,7);
v*=2.0;
print_line("scalar *=: "+v);
}
{
Vector3 v(4,5,7);
v/=2.0;
print_line("scalar /=: "+v);
}
#if 0
print_line(String("C:\\momo\\.\\popo\\..\\gongo").simplify_path());
print_line(String("res://../popo/..//gongo").simplify_path());
print_line(String("res://..").simplify_path());
DVector<uint8_t> a;
DVector<uint8_t> b;
a.resize(20);
b=a;
b.resize(30);
a=b;
#endif
#if 0
String za = String::utf8("á");
printf("unicode: %x\n",za[0]);
CharString cs=za.utf8();
for(int i=0;i<cs.size();i++) {
uint32_t v = uint8_t(cs[i]);
printf("%i - %x\n",i,v);
}
return NULL;
print_line(String("C:\\window\\system\\momo").path_to("C:\\window\\momonga"));
print_line(String("res://momo/sampler").path_to("res://pindonga"));
print_line(String("/margarito/terere").path_to("/margarito/pilates"));
print_line(String("/algo").path_to("/algo"));
print_line(String("c:").path_to("c:\\"));
print_line(String("/").path_to("/"));
print_line(itos(sizeof(Variant)));
return NULL;
Vector<StringName> path;
path.push_back("three");
path.push_back("two");
path.push_back("one");
path.push_back("comeon");
path.revert();
NodePath np(path,true);
print_line(np);
return NULL;
bool a=2;
print_line(Variant(a));
Matrix32 mat2_1;
mat2_1.rotate(0.5);
Matrix32 mat2_2;
mat2_2.translate(Vector2(1,2));
Matrix32 mat2_3 = mat2_1 * mat2_2;
mat2_3.affine_invert();
print_line(mat2_3.elements[0]);
print_line(mat2_3.elements[1]);
print_line(mat2_3.elements[2]);
Transform mat3_1;
mat3_1.basis.rotate(Vector3(0,0,1),0.5);
Transform mat3_2;
mat3_2.translate(Vector3(1,2,0));
Transform mat3_3 = mat3_1 * mat3_2;
mat3_3.affine_invert();
print_line(mat3_3.basis.get_axis(0));
print_line(mat3_3.basis.get_axis(1));
print_line(mat3_3.origin);
#endif
return NULL;
}
}

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,15 +26,15 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEST_MATH_H
#define TEST_MATH_H
#include "core/os/main_loop.h"
#include "os/main_loop.h"
namespace TestMath {
MainLoop *test();
MainLoop* test();
}
#endif

499
bin/tests/test_misc.cpp Normal file
View File

@ -0,0 +1,499 @@
/*************************************************************************/
/* test_misc.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_misc.h"
#include "servers/visual_server.h"
#include "os/main_loop.h"
#include "math_funcs.h"
#include "print_string.h"
namespace TestMisc {
struct ConvexTestResult
{
Vector3 edgeA[2];
Vector3 edgeB[2];
bool valid;
Vector3 contactA;
Vector3 contactB;
Vector3 contactNormal;
float depth;
/*
Vector3 contactA;
Vector3 contactB;
Vector3 contactNormal;
Vector3 contactX;
Vector3 contactY;
Vector3 edgeA[2];
Vector3 edgeB[2];
float depth;
bool valid;
bool isEdgeEdge;
bool needTransform;
neBool ComputerEdgeContactPoint(ConvexTestResult & res);
neBool ComputerEdgeContactPoint2(float & au, float & bu);
void Reverse()
{
neSwap(contactA, contactB);
contactNormal *= -1.0f;
}*/
bool ComputerEdgeContactPoint2(float & au, float & bu);
};
bool ConvexTestResult::ComputerEdgeContactPoint2(float & au, float & bu)
{
float d1343, d4321, d1321, d4343, d2121;
float numer, denom;
Vector3 p13;
Vector3 p43;
Vector3 p21;
Vector3 diff;
p13 = (edgeA[0]) - (edgeB[0]);
p43 = (edgeB[1]) - (edgeB[0]);
if ( p43.length_squared() < CMP_EPSILON2 )
{
valid = false;
goto ComputerEdgeContactPoint2_Exit;
}
p21 = (edgeA[1]) - (edgeA[0]);
if ( p21.length_squared()<CMP_EPSILON2 )
{
valid = false;
goto ComputerEdgeContactPoint2_Exit;
}
d1343 = p13.dot(p43);
d4321 = p43.dot(p21);
d1321 = p13.dot(p21);
d4343 = p43.dot(p43);
d2121 = p21.dot(p21);
denom = d2121 * d4343 - d4321 * d4321;
if (ABS(denom) < CMP_EPSILON)
{
valid = false;
goto ComputerEdgeContactPoint2_Exit;
}
numer = d1343 * d4321 - d1321 * d4343;
au = numer / denom;
bu = (d1343 + d4321 * (au)) / d4343;
if (au < 0.0f || au >= 1.0f)
{
valid = false;
}
else if (bu < 0.0f || bu >= 1.0f)
{
valid = false;
}
else
{
valid = true;
}
{
Vector3 tmpv;
tmpv = p21 * au;
contactA = (edgeA[0]) + tmpv;
tmpv = p43 * bu;
contactB = (edgeB[0]) + tmpv;
}
diff = contactA - contactB;
depth = Math::sqrt(diff.dot(diff));
return true;
ComputerEdgeContactPoint2_Exit:
return false;
}
struct neCollisionResult {
float depth;
bool penetrate;
Matrix3 collisionFrame;
Vector3 contactA;
Vector3 contactB;
};
struct TConvex {
float radius;
float half_height;
float CylinderRadius() const { return radius; }
float CylinderHalfHeight() const { return half_height; }
};
float GetDistanceFromLine2(Vector3 v, Vector3 & project, const Vector3 & pointA, const Vector3 & pointB)
{
Vector3 ba = pointB - pointA;
float len = ba.length();
if (len<CMP_EPSILON)
ba=Vector3();
else
ba *= 1.0f / len;
Vector3 pa = v - pointA;
float k = pa.dot(ba);
project = pointA + ba * k;
Vector3 diff = v - project;
return diff.length();
}
void TestCylinderVertEdge(neCollisionResult & result, Vector3 & edgeA1, Vector3 & edgeA2, Vector3 & vertB,
TConvex & cA, TConvex & cB, Transform & transA, Transform & transB, bool flip)
{
Vector3 project;
float dist = GetDistanceFromLine2(vertB,project, edgeA1, edgeA2);
float depth = cA.CylinderRadius() + cB.CylinderRadius() - dist;
if (depth <= 0.0f)
return;
if (depth <= result.depth)
return;
result.penetrate = true;
result.depth = depth;
if (!flip)
{
result.collisionFrame.set_axis(2,(project - vertB).normalized());
result.contactA = project - result.collisionFrame.get_axis(2) * cA.CylinderRadius();
result.contactB = vertB + result.collisionFrame.get_axis(2) * cB.CylinderRadius();
}
else
{
result.collisionFrame.set_axis(2,(vertB - project).normalized());
result.contactA = vertB - result.collisionFrame.get_axis(2) * cB.CylinderRadius();
result.contactB = project + result.collisionFrame.get_axis(2) * cA.CylinderRadius();
}
}
void TestCylinderVertVert(neCollisionResult & result, Vector3 & vertA, Vector3 & vertB,
TConvex & cA, TConvex & cB, Transform & transA, Transform & transB)
{
Vector3 diff = vertA - vertB;
float dist = diff.length();
float depth = cA.CylinderRadius() + cB.CylinderRadius() - dist;
if (depth <= 0.0f)
return;
if (depth <= result.depth)
return;
result.penetrate = true;
result.depth = depth;
result.collisionFrame.set_axis(2, diff * (1.0f / dist));
result.contactA = vertA - result.collisionFrame.get_axis(2) * cA.CylinderRadius();
result.contactB = vertB + result.collisionFrame.get_axis(2) * cB.CylinderRadius();
}
void Cylinder2CylinderTest(neCollisionResult & result, TConvex & cA, Transform & transA, TConvex & cB, Transform & transB)
{
result.penetrate = false;
Vector3 dir = transA.basis.get_axis(1).cross(transB.basis.get_axis(1));
float len = dir.length();
// bool isParallel = len<CMP_EPSILON;
// int doVertCheck = 0;
ConvexTestResult cr;
cr.edgeA[0] = transA.origin + transA.basis.get_axis(1) * cA.CylinderHalfHeight();
cr.edgeA[1] = transA.origin - transA.basis.get_axis(1) * cA.CylinderHalfHeight();
cr.edgeB[0] = transB.origin + transB.basis.get_axis(1) * cB.CylinderHalfHeight();
cr.edgeB[1] = transB.origin - transB.basis.get_axis(1) * cB.CylinderHalfHeight();
// float dot = transA.basis.get_axis(1).dot(transB.basis.get_axis(1));
if (len>CMP_EPSILON)
{
float au, bu;
cr.ComputerEdgeContactPoint2(au, bu);
if (cr.valid)
{
float depth = cA.CylinderRadius() + cB.CylinderRadius() - cr.depth;
if (depth <= 0.0f)
return;
result.depth = depth;
result.penetrate = true;
result.collisionFrame.set_axis(2, (cr.contactA - cr.contactB)*(1.0f / cr.depth));
result.contactA = cr.contactA - result.collisionFrame.get_axis(2) * cA.CylinderRadius();
result.contactB = cr.contactB + result.collisionFrame.get_axis(2) * cB.CylinderRadius();
return;
}
}
result.depth = -1.0e6f;
int i;
for (i = 0; i < 2; i++)
{
//project onto edge b
Vector3 diff = cr.edgeA[i] - cr.edgeB[1];
float dot = diff.dot(transB.basis.get_axis(1));
if (dot < 0.0f)
{
TestCylinderVertVert(result, cr.edgeA[i], cr.edgeB[1], cA, cB, transA, transB);
}
else if (dot > (2.0f * cB.CylinderHalfHeight()))
{
TestCylinderVertVert(result, cr.edgeA[i], cr.edgeB[0], cA, cB, transA, transB);
}
else
{
TestCylinderVertEdge(result, cr.edgeB[0], cr.edgeB[1], cr.edgeA[i], cB, cA, transB, transA, true);
}
}
for (i = 0; i < 2; i++)
{
//project onto edge b
Vector3 diff = cr.edgeB[i] - cr.edgeA[1];
float dot = diff.dot(transA.basis.get_axis(1));
if (dot < 0.0f)
{
TestCylinderVertVert(result, cr.edgeB[i], cr.edgeA[1], cA, cB, transA, transB);
}
else if (dot > (2.0f * cB.CylinderHalfHeight()))
{
TestCylinderVertVert(result, cr.edgeB[i], cr.edgeA[0], cA, cB, transA, transB);
}
else
{
TestCylinderVertEdge(result, cr.edgeA[0], cr.edgeA[1], cr.edgeB[i], cA, cB, transA, transB, false);
}
}
}
class TestMainLoop : public MainLoop {
RID meshA;
RID meshB;
RID poly;
RID instance;
RID camera;
RID viewport;
RID boxA;
RID boxB;
RID scenario;
Transform rot_a;
Transform rot_b;
bool quit;
public:
virtual void input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&BUTTON_MASK_LEFT) {
rot_b.origin.y+=-p_event.mouse_motion.relative_y/100.0;
rot_b.origin.x+=p_event.mouse_motion.relative_x/100.0;
}
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&BUTTON_MASK_MIDDLE) {
//rot_b.origin.x+=-p_event.mouse_motion.relative_y/100.0;
rot_b.origin.z+=p_event.mouse_motion.relative_x/100.0;
}
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&BUTTON_MASK_RIGHT) {
float rot_x=-p_event.mouse_motion.relative_y/100.0;
float rot_y=p_event.mouse_motion.relative_x/100.0;
rot_b.basis = rot_b.basis * Matrix3(Vector3(1,0,0),rot_x) * Matrix3(Vector3(0,1,0),rot_y);
}
}
virtual void request_quit() {
quit=true;
}
virtual void init() {
VisualServer *vs=VisualServer::get_singleton();
camera = vs->camera_create();
viewport = vs->viewport_create();
vs->viewport_attach_to_screen(viewport);
vs->viewport_attach_camera( viewport, camera );
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,0,3 ) ) );
/* CONVEX SHAPE */
DVector<Plane> cylinder_planes = Geometry::build_cylinder_planes(0.5,2,9,Vector3::AXIS_Y);
RID cylinder_material = vs->fixed_material_create();
vs->fixed_material_set_param( cylinder_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.8,0.2,0.9));
vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_ONTOP,true);
//vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_WIREFRAME,true);
vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_DOUBLE_SIDED,true);
vs->material_set_flag( cylinder_material, VisualServer::MATERIAL_FLAG_UNSHADED,true);
RID cylinder_mesh = vs->mesh_create();
Geometry::MeshData cylinder_data = Geometry::build_convex_mesh(cylinder_planes);
vs->mesh_add_surface_from_mesh_data(cylinder_mesh,cylinder_data);
vs->mesh_surface_set_material( cylinder_mesh, 0, cylinder_material );
meshA=vs->instance_create2(cylinder_mesh,scenario);
meshB=vs->instance_create2(cylinder_mesh,scenario);
boxA=vs->instance_create2(vs->get_test_cube(),scenario);
boxB=vs->instance_create2(vs->get_test_cube(),scenario);
/*
RID lightaux = vs->light_create( VisualServer::LIGHT_OMNI );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_RADIUS, 80 );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ATTENUATION, 1 );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ENERGY, 1.5 );
light = vs->instance_create2( lightaux );
*/
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
//vs->light_set_shadow( lightaux, true );
RID light = vs->instance_create2( lightaux,scenario );
//rot_a=Transform(Matrix3(Vector3(1,0,0),Math_PI/2.0),Vector3());
rot_b=Transform(Matrix3(),Vector3(2,0,0));
//rot_x=0;
//rot_y=0;
quit=false;
}
virtual bool idle(float p_time) {
VisualServer *vs=VisualServer::get_singleton();
vs->instance_set_transform(meshA,rot_a);
vs->instance_set_transform(meshB,rot_b);
neCollisionResult res;
TConvex a;
a.radius=0.5;
a.half_height=1;
Cylinder2CylinderTest(res,a,rot_a,a,rot_b);
if (res.penetrate) {
Matrix3 scale;
scale.scale(Vector3(0.1,0.1,0.1));
vs->instance_set_transform(boxA,Transform(scale,res.contactA));
vs->instance_set_transform(boxB,Transform(scale,res.contactB));
print_line("depth: "+rtos(res.depth));
} else {
Matrix3 scale;
scale.scale(Vector3());
vs->instance_set_transform(boxA,Transform(scale,res.contactA));
vs->instance_set_transform(boxB,Transform(scale,res.contactB));
}
print_line("collided: "+itos(res.penetrate));
return false;
}
virtual bool iteration(float p_time) {
return quit;
}
virtual void finish() {
}
};
MainLoop* test() {
return memnew( TestMainLoop );
}
}

40
bin/tests/test_misc.h Normal file
View File

@ -0,0 +1,40 @@
/*************************************************************************/
/* test_misc.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 TEST_MISC_H
#define TEST_MISC_H
#include "os/main_loop.h"
namespace TestMisc {
MainLoop* test();
}
#endif

View File

@ -0,0 +1,121 @@
/*************************************************************************/
/* test_particles.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_particles.h"
#include "servers/visual_server.h"
#include "os/main_loop.h"
#include "math_funcs.h"
#include "print_string.h"
namespace TestParticles {
class TestMainLoop : public MainLoop {
RID particles;
RID instance;
RID camera;
RID viewport;
RID light;
RID scenario;
struct InstanceInfo {
RID instance;
Transform base;
Vector3 rot_axis;
};
List<InstanceInfo> instances;
float ofs;
bool quit;
public:
virtual void input_event(const InputEvent& p_event) {
}
virtual void request_quit() {
quit=true;
}
virtual void init() {
VisualServer *vs=VisualServer::get_singleton();
particles = vs->particles_create();
vs->particles_set_amount(particles,1000);
instance = vs->instance_create2(particles,scenario);
camera = vs->camera_create();
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create();
vs->viewport_attach_camera( viewport, camera );
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,0,20 ) ) );
/*
RID lightaux = vs->light_create( VisualServer::LIGHT_OMNI );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_RADIUS, 80 );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ATTENUATION, 1 );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ENERGY, 1.5 );
light = vs->instance_create2( lightaux );
*/
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
light = vs->instance_create2( lightaux, scenario );
ofs=0;
quit=false;
}
virtual bool idle(float p_time) {
return false;
}
virtual bool iteration(float p_time) {
// VisualServer *vs=VisualServer::get_singleton();
ofs+=p_time;
return quit;
}
virtual void finish() {
}
};
MainLoop* test() {
return memnew( TestMainLoop );
}
}

View File

@ -0,0 +1,43 @@
/*************************************************************************/
/* test_particles.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 TEST_PARTICLES_H
#define TEST_PARTICLES_H
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#include "os/main_loop.h"
namespace TestParticles {
MainLoop* test();
}
#endif

662
bin/tests/test_physics.cpp Normal file
View File

@ -0,0 +1,662 @@
/*************************************************************************/
/* test_physics.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_physics.h"
#include "servers/visual_server.h"
#include "servers/physics_server.h"
#include "os/main_loop.h"
#include "math_funcs.h"
#include "print_string.h"
#include "map.h"
#include "os/os.h"
#include "quick_hull.h"
class TestPhysicsMainLoop : public MainLoop {
OBJ_TYPE( TestPhysicsMainLoop, MainLoop );
enum {
LINK_COUNT = 20,
};
RID test_cube;
RID plane;
RID sphere;
RID light;
RID camera;
RID mover;
RID scenario;
RID space;
RID character;
float ofs_x,ofs_y;
Point2 joy_direction;
List<RID> bodies;
Map<PhysicsServer::ShapeType,RID> type_shape_map;
Map<PhysicsServer::ShapeType,RID> type_mesh_map;
void body_changed_transform(Object *p_state, RID p_visual_instance) {
PhysicsDirectBodyState *state = (PhysicsDirectBodyState*)p_state;
VisualServer *vs=VisualServer::get_singleton();
Transform t=state->get_transform();
//t.basis.scale( Vector3(1.0,0.5,0.2) );
vs->instance_set_transform(p_visual_instance,t);
}
bool quit;
protected:
static void _bind_methods() {
ObjectTypeDB::bind_method("body_changed_transform",&TestPhysicsMainLoop::body_changed_transform);
}
RID create_body(PhysicsServer::ShapeType p_shape, PhysicsServer::BodyMode p_body,const Transform p_location,bool p_active_default=true,const Transform&p_shape_xform=Transform()) {
VisualServer *vs=VisualServer::get_singleton();
PhysicsServer * ps = PhysicsServer::get_singleton();
RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape],scenario);
RID body = ps->body_create(p_body,!p_active_default);
ps->body_set_space(body,space);
ps->body_set_param(body,PhysicsServer::BODY_PARAM_BOUNCE,0.0);
//todo set space
ps->body_add_shape(body,type_shape_map[p_shape]);
ps->body_set_force_integration_callback(body,this,"body_changed_transform",mesh_instance);
ps->body_set_state( body, PhysicsServer::BODY_STATE_TRANSFORM,p_location);
bodies.push_back(body);
if (p_body==PhysicsServer::BODY_MODE_STATIC) {
vs->instance_set_transform(mesh_instance,p_location);
}
return body;
}
RID create_static_plane(const Plane& p_plane) {
PhysicsServer * ps = PhysicsServer::get_singleton();
RID plane_shape = ps->shape_create(PhysicsServer::SHAPE_PLANE);;
ps->shape_set_data( plane_shape, p_plane );
RID b = ps->body_create( PhysicsServer::BODY_MODE_STATIC );
ps->body_set_space(b,space);
//todo set space
ps->body_add_shape(b, plane_shape);
return b;
}
void configure_body(RID p_body,float p_mass, float p_friction, float p_bounce) {
PhysicsServer * ps = PhysicsServer::get_singleton();
ps->body_set_param( p_body, PhysicsServer::BODY_PARAM_MASS, p_mass );
ps->body_set_param( p_body, PhysicsServer::BODY_PARAM_FRICTION, p_friction );
ps->body_set_param( p_body, PhysicsServer::BODY_PARAM_BOUNCE, p_bounce );
}
void init_shapes() {
VisualServer *vs=VisualServer::get_singleton();
PhysicsServer * ps = PhysicsServer::get_singleton();
/* SPHERE SHAPE */
RID sphere_mesh = vs->make_sphere_mesh(10,20,0.5);
RID sphere_material = vs->fixed_material_create();
//vs->material_set_flag( sphere_material, VisualServer::MATERIAL_FLAG_WIREFRAME, true );
vs->fixed_material_set_param( sphere_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.7,0.8,3.0) );
vs->mesh_surface_set_material( sphere_mesh, 0, sphere_material );
type_mesh_map[PhysicsServer::SHAPE_SPHERE]=sphere_mesh;
RID sphere_shape=ps->shape_create(PhysicsServer::SHAPE_SPHERE);
ps->shape_set_data( sphere_shape, 0.5 );
type_shape_map[PhysicsServer::SHAPE_SPHERE]=sphere_shape;
/* BOX SHAPE */
DVector<Plane> box_planes = Geometry::build_box_planes(Vector3(0.5,0.5,0.5));
RID box_material = vs->fixed_material_create();
vs->fixed_material_set_param( box_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(1.0,0.2,0.2) );
RID box_mesh = vs->mesh_create();
Geometry::MeshData box_data = Geometry::build_convex_mesh(box_planes);
vs->mesh_add_surface_from_mesh_data(box_mesh,box_data);
vs->mesh_surface_set_material( box_mesh, 0, box_material );
type_mesh_map[PhysicsServer::SHAPE_BOX]=box_mesh;
RID box_shape=ps->shape_create(PhysicsServer::SHAPE_BOX);
ps->shape_set_data( box_shape, Vector3(0.5,0.5,0.5) );
type_shape_map[PhysicsServer::SHAPE_BOX]=box_shape;
/* CAPSULE SHAPE */
DVector<Plane> capsule_planes = Geometry::build_capsule_planes(0.5,0.7,12,Vector3::AXIS_Z);
RID capsule_material = vs->fixed_material_create();
vs->fixed_material_set_param( capsule_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.3,0.4,1.0) );
RID capsule_mesh = vs->mesh_create();
Geometry::MeshData capsule_data = Geometry::build_convex_mesh(capsule_planes);
vs->mesh_add_surface_from_mesh_data(capsule_mesh,capsule_data);
vs->mesh_surface_set_material( capsule_mesh, 0, capsule_material );
type_mesh_map[PhysicsServer::SHAPE_CAPSULE]=capsule_mesh;
RID capsule_shape=ps->shape_create(PhysicsServer::SHAPE_CAPSULE);
Dictionary capsule_params;
capsule_params["radius"]=0.5;
capsule_params["height"]=1.4;
ps->shape_set_data( capsule_shape, capsule_params );
type_shape_map[PhysicsServer::SHAPE_CAPSULE]=capsule_shape;
/* CONVEX SHAPE */
DVector<Plane> convex_planes = Geometry::build_cylinder_planes(0.5,0.7,5,Vector3::AXIS_Z);
RID convex_material = vs->fixed_material_create();
vs->fixed_material_set_param( convex_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(0.8,0.2,0.9));
RID convex_mesh = vs->mesh_create();
Geometry::MeshData convex_data = Geometry::build_convex_mesh(convex_planes);
QuickHull::build(convex_data.vertices,convex_data);
vs->mesh_add_surface_from_mesh_data(convex_mesh,convex_data);
vs->mesh_surface_set_material( convex_mesh, 0, convex_material );
type_mesh_map[PhysicsServer::SHAPE_CONVEX_POLYGON]=convex_mesh;
RID convex_shape=ps->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON);
ps->shape_set_data( convex_shape, convex_data.vertices );
type_shape_map[PhysicsServer::SHAPE_CONVEX_POLYGON]=convex_shape;
}
void make_trimesh(Vector<Vector3> p_faces,const Transform& p_xform=Transform()) {
VisualServer *vs=VisualServer::get_singleton();
PhysicsServer * ps = PhysicsServer::get_singleton();
RID trimesh_shape = ps->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON);
ps->shape_set_data(trimesh_shape, p_faces);
p_faces=ps->shape_get_data(trimesh_shape); // optimized one
Vector<Vector3> normals; // for drawing
for (int i=0;i<p_faces.size()/3;i++) {
Plane p( p_faces[i*3+0],p_faces[i*3+1], p_faces[i*3+2] );
normals.push_back(p.normal);
normals.push_back(p.normal);
normals.push_back(p.normal);
}
RID trimesh_mesh = vs->mesh_create();
Array d;
d.resize(VS::ARRAY_MAX);
d[VS::ARRAY_VERTEX]=p_faces;
d[VS::ARRAY_NORMAL]=normals;
vs->mesh_add_surface(trimesh_mesh, VS::PRIMITIVE_TRIANGLES, d );
RID trimesh_mat = vs->fixed_material_create();
vs->fixed_material_set_param( trimesh_mat, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(1.0,0.5,0.8));
//vs->material_set_flag( trimesh_mat, VisualServer::MATERIAL_FLAG_UNSHADED,true);
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat );
RID triins = vs->instance_create2(trimesh_mesh,scenario);
RID tribody = ps->body_create( PhysicsServer::BODY_MODE_STATIC);
ps->body_set_space(tribody,space);
//todo set space
ps->body_add_shape(tribody, trimesh_shape);
Transform tritrans = p_xform;
ps->body_set_state( tribody, PhysicsServer::BODY_STATE_TRANSFORM, tritrans );
vs->instance_set_transform( triins, tritrans );
//RID trimesh_material = vs->fixed_material_create();
//vs->material_generate( trimesh_material, Color(0.2,0.4,0.6) );
//vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_material );
}
void make_grid(int p_width,int p_height,float p_cellsize,float p_cellheight,const Transform& p_xform=Transform()) {
Vector< Vector< float > > grid;
grid.resize(p_width);
for (int i=0;i<p_width;i++) {
grid[i].resize(p_height);
for (int j=0;j<p_height;j++) {
grid[i][j]=1.0+Math::random(-p_cellheight, p_cellheight );
}
}
Vector<Vector3> faces;
for (int i=1;i<p_width;i++) {
for (int j=1;j<p_height;j++) {
#define MAKE_VERTEX(m_x,m_z)\
faces.push_back( Vector3( (m_x-p_width/2)*p_cellsize, grid[m_x][m_z], (m_z-p_height/2)*p_cellsize ) )
MAKE_VERTEX(i,j-1);
MAKE_VERTEX(i,j);
MAKE_VERTEX(i-1,j);
MAKE_VERTEX(i-1,j-1);
MAKE_VERTEX(i,j-1);
MAKE_VERTEX(i-1,j);
}
}
make_trimesh(faces,p_xform);
}
public:
virtual void input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
ofs_y-=p_event.mouse_motion.relative_y/200.0;
ofs_x+=p_event.mouse_motion.relative_x/200.0;
}
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&1) {
float y=-p_event.mouse_motion.relative_y/20.0;
float x=p_event.mouse_motion.relative_x/20.0;
if (mover.is_valid()) {
PhysicsServer * ps = PhysicsServer::get_singleton();
Transform t = ps->body_get_state(mover,PhysicsServer::BODY_STATE_TRANSFORM);
t.origin+=Vector3(x,y,0);
ps->body_set_state(mover,PhysicsServer::BODY_STATE_TRANSFORM,t);
}
}
if (p_event.type == InputEvent::JOYSTICK_MOTION) {
if (p_event.joy_motion.axis == 0) {
joy_direction.x = p_event.joy_motion.axis_value;
};
if (p_event.joy_motion.axis == 1) {
joy_direction.y = p_event.joy_motion.axis_value;
};
};
}
virtual void request_quit() {
quit=true;
}
virtual void init() {
ofs_x=ofs_y=0;
init_shapes();
PhysicsServer *ps = PhysicsServer::get_singleton();
space=ps->space_create();
ps->space_set_active(space,true);
VisualServer *vs=VisualServer::get_singleton();
/* LIGHT */
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
scenario = vs->scenario_create();
vs->light_set_shadow(lightaux,true);
light = vs->instance_create2( lightaux,scenario );
Transform t;
t.rotate(Vector3(1.0,0,0),0.6);
vs->instance_set_transform(light,t);
/* CAMERA */
camera = vs->camera_create();
RID viewport = vs->viewport_create();
vs->viewport_attach_camera( viewport, camera );
vs->viewport_attach_to_screen(viewport);
vs->viewport_set_scenario( viewport, scenario );
vs->camera_set_perspective(camera,60,0.1,40.0);
vs->camera_set_transform(camera,Transform( Matrix3(), Vector3(0,9,12)));
//vs->scenario_set_debug(scenario,VS::SCENARIO_DEBUG_WIREFRAME);
Transform gxf;
gxf.basis.scale(Vector3(1.4,0.4,1.4));
gxf.origin=Vector3(-2,1,-2);
make_grid(5,5,2.5,1,gxf);
// create_body(PhysicsServer::SHAPE_BOX,PhysicsServer::BODY_MODE_STATIC,gxf);
//create_static_plane( Plane( Vector3(0,1,0), -2) );
// test_joint();
test_fall();
//test_joint();
/*
Vector<Vector3> faces;
faces.push_back( Vector3(10,0,-5) );
faces.push_back( Vector3(0,0,10) );
faces.push_back( Vector3(-10,-0.2,-5) );
make_trimesh(faces);
*/
/* Make Trimesh */
quit=false;
return;
#if 0
#define GRID_SIZE 5
float grid[GRID_SIZE][GRID_SIZE];
for (int i=0;i<GRID_SIZE;i++) {
for (int j=0;j<GRID_SIZE;j++) {
grid[j][i]=Math::random(0.0, 1.0 );
}
}
Vector<Vector3> faces;
for (int i=1;i<GRID_SIZE;i++) {
for (int j=1;j<GRID_SIZE;j++) {
#define MAKE_VERTEX(m_x,m_z)\
faces.push_back( Vector3( m_x-GRID_SIZE/2.0, grid[m_x][m_z], m_z-GRID_SIZE/2.0 )*3.0 )
MAKE_VERTEX(i,j-1);
MAKE_VERTEX(i,j);
MAKE_VERTEX(i-1,j);
MAKE_VERTEX(i-1,j-1);
MAKE_VERTEX(i,j-1);
MAKE_VERTEX(i-1,j);
}
}
/*
faces.clear();
faces.push_back( Vector3(0,0,-5) );
faces.push_back( Vector3(1,0,-1) );
faces.push_back( Vector3(-1,-0,-1) );
*/
RID trimesh_shape = ps->shape_create();
ps->shape_set_data(trimesh_shape, PhysicsServer::SHAPE_CONCAVE_POLYGON,faces);
faces=ps->shape_get_shape(trimesh_shape, 0);
Vector<Vector3> normals; // for drawing
for (int i=0;i<faces.size()/3;i++) {
Plane p( faces[i*3+0],faces[i*3+1], faces[i*3+2] );
normals.push_back(p.normal);
normals.push_back(p.normal);
normals.push_back(p.normal);
}
RID trimesh_mesh = vs->mesh_create();
vs->mesh_add_surface(trimesh_mesh, VS::PRIMITIVE_TRIANGLES, VS::ARRAY_FORMAT_VERTEX|VS::ARRAY_FORMAT_NORMAL, faces.size() );
vs->mesh_surface_set_array(trimesh_mesh,0,VS::ARRAY_VERTEX, faces );
vs->mesh_surface_set_array(trimesh_mesh,0,VS::ARRAY_NORMAL, normals );
RID trimesh_mat = vs->fixed_material_create();
vs->material_generate( trimesh_mat, Color(1.0,0.5,0.3) );
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat );
RID triins = vs->instance_create2(trimesh_mesh);
RID tribody = ps->body_create( PhysicsServer::BODY_MODE_STATIC, trimesh_shape);
Transform tritrans = Transform( Matrix3(), Vector3(0,0,-2) );
ps->body_set_state( tribody, PhysicsServer::BODY_STATE_TRANSFORM, tritrans );
vs->instance_set_transform( triins, tritrans );
RID trimesh_material = vs->fixed_material_create();
vs->material_generate( trimesh_material, Color(0.2,0.4,0.6) );
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_material );
#endif
}
virtual bool iteration(float p_time) {
if (mover) {
static float joy_speed = 10;
PhysicsServer * ps = PhysicsServer::get_singleton();
Transform t = ps->body_get_state(mover,PhysicsServer::BODY_STATE_TRANSFORM);
t.origin+=Vector3(joy_speed * joy_direction.x * p_time, -joy_speed * joy_direction.y * p_time,0);
ps->body_set_state(mover,PhysicsServer::BODY_STATE_TRANSFORM,t);
};
Transform cameratr;
cameratr.rotate(Vector3(0,1,0),ofs_x);
cameratr.rotate(Vector3(1,0,0),-ofs_y);
cameratr.translate(Vector3(0,2,8));
VisualServer *vs=VisualServer::get_singleton();
vs->camera_set_transform(camera,cameratr);
return quit;
}
virtual void finish() {
}
void test_joint() {
#if 0
PhysicsServer * ps = PhysicsServer::get_singleton();
mover = create_body(PhysicsServer::SHAPE_BOX,PhysicsServer::BODY_MODE_STATIC,Transform(Matrix3(),Vector3(0,0,-24)));
RID b = create_body(PhysicsServer::SHAPE_CAPSULE,PhysicsServer::BODY_MODE_RIGID,Transform());
ps->joint_create_double_pin(b,Vector3(0,0,1.0),mover,Vector3(0,0,0));
ps->body_add_collision_exception(mover,b);
List<String> cmdline = OS::get_singleton()->get_cmdline_args();
int link_count = LINK_COUNT;
if (cmdline.size() > 0 && cmdline[cmdline.size()-1].to_int()) {
link_count = cmdline[cmdline.size()-1].to_int();
};
for(int i=0;i<link_count;i++) {
RID c = create_body(PhysicsServer::SHAPE_CAPSULE,PhysicsServer::BODY_MODE_RIGID,Transform());
ps->joint_create_double_pin(b,Vector3(0,0,-0.7),c,Vector3(0,0,0.7));
ps->body_add_collision_exception(c,b);
b=c;
}
create_static_plane(Plane(Vector3(0,1,0),-8));
#endif
}
void test_hinge() {
#if 0
PhysicsServer * ps = PhysicsServer::get_singleton();
mover = create_body(PhysicsServer::SHAPE_BOX,PhysicsServer::BODY_MODE_STATIC,Transform(Matrix3(),Vector3(0,0,-24)));
RID b = create_body(PhysicsServer::SHAPE_BOX,PhysicsServer::BODY_MODE_RIGID,Transform());
ps->joint_create_double_hinge(b,Transform(Matrix3(),Vector3(1,1,1.0)),mover,Transform(Matrix3(),Vector3(0,0,0)));
ps->body_add_collision_exception(mover,b);
/*
for(int i=0;i<20;i++) {
RID c = create_body(PhysicsServer::SHAPE_CAPSULE,PhysicsServer::BODY_MODE_RIGID,Transform());
ps->joint_create_double_hinge(b,Transform(Matrix3(),Vector3(0,0,-0.7)),c,Transform(Matrix3(),Vector3(0,0,0.7)));
ps->body_add_collision_exception(c,b);
b=c;
}
*/
//create_static_plane(Plane(Vector3(0,1,0),-8));
#endif
}
void test_character() {
VisualServer *vs=VisualServer::get_singleton();
PhysicsServer * ps = PhysicsServer::get_singleton();
DVector<Plane> capsule_planes = Geometry::build_capsule_planes(0.5,1,12,5,Vector3::AXIS_Y);
RID capsule_material = vs->fixed_material_create();
vs->fixed_material_set_param( capsule_material, VisualServer::FIXED_MATERIAL_PARAM_DIFFUSE, Color(1,1,1) );
RID capsule_mesh = vs->mesh_create();
Geometry::MeshData capsule_data = Geometry::build_convex_mesh(capsule_planes);
vs->mesh_add_surface_from_mesh_data(capsule_mesh,capsule_data);
vs->mesh_surface_set_material( capsule_mesh, 0, capsule_material );
type_mesh_map[PhysicsServer::SHAPE_CAPSULE]=capsule_mesh;
RID capsule_shape=ps->shape_create(PhysicsServer::SHAPE_CAPSULE);
Dictionary capsule_params;
capsule_params["radius"]=0.5;
capsule_params["height"]=1;
Transform shape_xform;
shape_xform.rotate(Vector3(1,0,0),Math_PI/2.0);
//shape_xform.origin=Vector3(1,1,1);
ps->shape_set_data( capsule_shape, capsule_params);
RID mesh_instance = vs->instance_create2(capsule_mesh,scenario);
character = ps->body_create(PhysicsServer::BODY_MODE_CHARACTER);
ps->body_set_space(character,space);
//todo add space
ps->body_add_shape(character,capsule_shape);
ps->body_set_force_integration_callback(character,this,"body_changed_transform",mesh_instance);
ps->body_set_state( character, PhysicsServer::BODY_STATE_TRANSFORM,Transform(Matrix3(),Vector3(-2,5,-2)));
bodies.push_back(character);
}
void test_fall() {
for (int i=0;i<35;i++) {
static const PhysicsServer::ShapeType shape_idx[]={
PhysicsServer::SHAPE_CAPSULE,
PhysicsServer::SHAPE_BOX,
PhysicsServer::SHAPE_SPHERE,
PhysicsServer::SHAPE_CONVEX_POLYGON
};
PhysicsServer::ShapeType type=shape_idx[i%4];
//type=PhysicsServer::SHAPE_CONVEX_POLYGON;
Transform t;
t.origin=Vector3(0.0*i,3.5+1.1*i,0.7+0.0*i);
//t.origin=Vector3(-0.7+0.0*i,0.5+4.1*i,0);
t.basis.rotate(Vector3(0.2,-1,0),Math_PI/2*0.6);
//t.basis.rotate(Vector3(0,-1,0),Math_PI/4*i);
//t.basis.rotate(Vector3(0,-1,0),Math_PI/4*i);
//t.basis.rotate(Vector3(-1,0,0),Math_PI/4*i);
RID b = create_body(type,PhysicsServer::BODY_MODE_RIGID,t);
//RID b = create_body(type,i==0?PhysicsServer::BODY_MODE_STATIC:PhysicsServer::BODY_MODE_RIGID,t);
}
create_static_plane( Plane( Vector3(0,1,0), -1) );
/*
create_static_plane( Plane( Vector3(1,0,0), -2) );
create_static_plane( Plane( Vector3(-1,0,0), -2) );
create_static_plane( Plane( Vector3(0,0,1), -2) );
create_static_plane( Plane( Vector3(0,0,-1), -2) );
*/
}
void test_activate() {
create_body(PhysicsServer::SHAPE_BOX,PhysicsServer::BODY_MODE_RIGID,Transform(Matrix3(),Vector3(0,2,0)),true);
//create_body(PhysicsServer::SHAPE_SPHERE,PhysicsServer::BODY_MODE_RIGID,Transform(Matrix3(),Vector3(0,6,0)),true);
create_static_plane( Plane( Vector3(0,1,0), -1) );
}
virtual bool idle(float p_time) {
return false;
}
TestPhysicsMainLoop() {
}
};
namespace TestPhysics {
MainLoop* test() {
return memnew( TestPhysicsMainLoop );
}
}

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,15 +26,19 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEST_PHYSICS_H
#define TEST_PHYSICS_H
#include "core/os/main_loop.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#include "os/main_loop.h"
namespace TestPhysics {
MainLoop *test();
MainLoop* test();
}
#endif

File diff suppressed because one or more lines are too long

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,15 +26,16 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEST_PHYSICS_2D_H
#define TEST_PHYSICS_2D_H
#include "core/os/main_loop.h"
#include "os/main_loop.h"
namespace TestPhysics2D {
MainLoop *test();
MainLoop* test();
}
#endif // TEST_PHYSICS_2D_H

56
bin/tests/test_python.cpp Normal file
View File

@ -0,0 +1,56 @@
/*************************************************************************/
/* test_python.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_python.h"
#ifdef PYTHON_ENABLED
#include "Python.h"
#include "print_string.h"
namespace TestPython {
void test() {
print_line("testing python");
PyRun_SimpleString("import engine\n");
PyRun_SimpleString("def test(self):\n\tprint(\"noway\")\n");
PyRun_SimpleString("a=engine.ObjectPtr()\n");
PyRun_SimpleString("a.noway(22,'hello')\n");
PyRun_SimpleString("a.normalize()\n");
PyRun_SimpleString("class Moch(engine.ObjectPtr):\n\tdef mooch(self):\n\t\tprint('muchi')\n");
PyRun_SimpleString("b=Moch();\n");
PyRun_SimpleString("b.mooch();\n");
PyRun_SimpleString("b.meis();\n");
}
}
#endif

43
bin/tests/test_python.h Normal file
View File

@ -0,0 +1,43 @@
/*************************************************************************/
/* test_python.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 TEST_PYTHON_H
#define TEST_PYTHON_H
#ifdef PYTHON_ENABLED
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
namespace TestPython {
void test();
}
#endif
#endif

263
bin/tests/test_render.cpp Normal file
View File

@ -0,0 +1,263 @@
/*************************************************************************/
/* test_render.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_render.h"
#include "servers/visual_server.h"
#include "os/main_loop.h"
#include "math_funcs.h"
#include "print_string.h"
#include "os/os.h"
#include "quick_hull.h"
#include "os/keyboard.h"
#define OBJECT_COUNT 50
namespace TestRender {
class TestMainLoop : public MainLoop {
RID test_cube;
RID instance;
RID camera;
RID viewport;
RID light;
RID scenario;
struct InstanceInfo {
RID instance;
Transform base;
Vector3 rot_axis;
};
List<InstanceInfo> instances;
float ofs;
bool quit;
protected:
public:
virtual void input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::KEY && p_event.key.pressed)
quit=true;
}
virtual void init() {
print_line("INITIALIZING TEST RENDER");
VisualServer *vs=VisualServer::get_singleton();
test_cube = vs->get_test_cube();
scenario = vs->scenario_create();
Vector<Vector3> vts;
/*
DVector<Plane> sp = Geometry::build_sphere_planes(2,5,5);
Geometry::MeshData md2 = Geometry::build_convex_mesh(sp);
vts=md2.vertices;
*/
/*
static const int s = 20;
for(int i=0;i<s;i++) {
Matrix3 rot(Vector3(0,1,0),i*Math_PI/s);
for(int j=0;j<s;j++) {
Vector3 v;
v.x=Math::sin(j*Math_PI*2/s);
v.y=Math::cos(j*Math_PI*2/s);
vts.push_back( rot.xform(v*2 ) );
}
}*/
/*for(int i=0;i<100;i++) {
vts.push_back( Vector3(Math::randf()*2-1.0,Math::randf()*2-1.0,Math::randf()*2-1.0).normalized()*2);
}*/
/*
vts.push_back(Vector3(0,0,1));
vts.push_back(Vector3(0,0,-1));
vts.push_back(Vector3(0,1,0));
vts.push_back(Vector3(0,-1,0));
vts.push_back(Vector3(1,0,0));
vts.push_back(Vector3(-1,0,0));*/
vts.push_back(Vector3(1,1,1));
vts.push_back(Vector3(1,-1,1));
vts.push_back(Vector3(-1,1,1));
vts.push_back(Vector3(-1,-1,1));
vts.push_back(Vector3(1,1,-1));
vts.push_back(Vector3(1,-1,-1));
vts.push_back(Vector3(-1,1,-1));
vts.push_back(Vector3(-1,-1,-1));
Geometry::MeshData md;
Error err = QuickHull::build(vts,md);
print_line("ERR: "+itos(err));
test_cube = vs->mesh_create();
vs->mesh_add_surface_from_mesh_data(test_cube,md);
//vs->scenario_set_debug(scenario,VS::SCENARIO_DEBUG_WIREFRAME);
/*
RID sm = vs->shader_create();
//vs->shader_set_fragment_code(sm,"OUT_ALPHA=mod(TIME,1);");
//vs->shader_set_vertex_code(sm,"OUT_VERTEX=IN_VERTEX*mod(TIME,1);");
vs->shader_set_fragment_code(sm,"OUT_DIFFUSE=vec3(1,0,1);OUT_GLOW=abs(sin(TIME));");
RID tcmat = vs->mesh_surface_get_material(test_cube,0);
vs->material_set_shader(tcmat,sm);
*/
List<String> cmdline = OS::get_singleton()->get_cmdline_args();
int object_count = OBJECT_COUNT;
if (cmdline.size() > 0 && cmdline[cmdline.size()-1].to_int()) {
object_count = cmdline[cmdline.size()-1].to_int();
};
for (int i=0;i<object_count;i++) {
InstanceInfo ii;
ii.instance = vs->instance_create2( test_cube, scenario );
ii.base.translate( Math::random(-20,20), Math::random(-20,20),Math::random(-20,18) );
ii.base.rotate( Vector3(0,1,0), Math::randf() * Math_PI );
ii.base.rotate( Vector3(1,0,0), Math::randf() * Math_PI );
vs->instance_set_transform( ii.instance, ii.base );
ii.rot_axis = Vector3( Math::random(-1,1), Math::random(-1,1), Math::random(-1,1) ).normalized();
instances.push_back(ii);
}
camera = vs->camera_create();
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create();
vs->viewport_attach_to_screen(viewport);
vs->viewport_attach_camera( viewport, camera );
vs->viewport_set_scenario( viewport, scenario );
vs->camera_set_transform(camera, Transform( Matrix3(), Vector3(0,3,30 ) ) );
vs->camera_set_perspective( camera, 60, 0.1, 1000);
/*
RID lightaux = vs->light_create( VisualServer::LIGHT_OMNI );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_RADIUS, 80 );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ATTENUATION, 1 );
vs->light_set_var( lightaux, VisualServer::LIGHT_VAR_ENERGY, 1.5 );
light = vs->instance_create( lightaux );
*/
RID lightaux;
//*
lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_DIFFUSE, Color(1.0,1.0,1.0) );
//vs->light_set_shadow( lightaux, true );
light = vs->instance_create2( lightaux, scenario );
Transform lla;
//lla.set_look_at(Vector3(),Vector3(1,-1,1),Vector3(0,1,0));
lla.set_look_at(Vector3(),Vector3(-0.000000,-0.836026,-0.548690),Vector3(0,1,0));
vs->instance_set_transform( light, lla );
// */
//*
lightaux = vs->light_create( VisualServer::LIGHT_OMNI );
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,1.0) );
vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_DIFFUSE, Color(1.0,1.0,0.0) );
vs->light_set_param( lightaux, VisualServer::LIGHT_PARAM_RADIUS, 4 );
vs->light_set_param( lightaux, VisualServer::LIGHT_PARAM_ENERGY, 8 );
//vs->light_set_shadow( lightaux, true );
//light = vs->instance_create( lightaux );
// */
ofs=0;
quit=false;
}
virtual bool iteration(float p_time) {
VisualServer *vs=VisualServer::get_singleton();
//Transform t;
//t.rotate(Vector3(0, 1, 0), ofs);
//t.translate(Vector3(0,0,20 ));
//vs->camera_set_transform(camera, t);
ofs+=p_time*0.05;
//return quit;
for(List<InstanceInfo>::Element *E=instances.front();E;E=E->next()) {
Transform pre( Matrix3(E->get().rot_axis, ofs), Vector3() );
vs->instance_set_transform( E->get().instance, pre * E->get().base );
/*
if( !E->next() ) {
vs->free( E->get().instance );
instances.erase(E );
}*/
}
return quit;
}
virtual bool idle(float p_time) {
return quit;
}
virtual void finish() {
}
};
MainLoop* test() {
return memnew( TestMainLoop );
}
}

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,15 +26,19 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEST_RENDER_H
#define TEST_RENDER_H
#include "core/os/main_loop.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#include "os/main_loop.h"
namespace TestRender {
MainLoop *test();
MainLoop* test();
}
#endif

View File

@ -0,0 +1,340 @@
/*************************************************************************/
/* test_shader_lang.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_shader_lang.h"
#include "os/main_loop.h"
#include "os/os.h"
#include "os/file_access.h"
#include "scene/gui/control.h"
#include "scene/gui/text_edit.h"
#include "print_string.h"
#include "servers/visual/shader_language.h"
#include "drivers/gles2/shader_compiler_gles2.h"
typedef ShaderLanguage SL;
namespace TestShaderLang {
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) {
switch(p_type) {
case SL::TYPE_VOID: return "void";
case SL::TYPE_BOOL: return "bool";
case SL::TYPE_FLOAT: return "float";
case SL::TYPE_VEC2: return "vec2";
case SL::TYPE_VEC3: return "vec3";
case SL::TYPE_VEC4: return "vec4";
case SL::TYPE_MAT3: return "mat3";
case SL::TYPE_MAT4: return "mat4";
case SL::TYPE_TEXTURE: return "texture";
case SL::TYPE_CUBEMAP: return "cubemap";
default: {}
}
return "";
}
static String _opstr(SL::Operator p_op) {
switch(p_op) {
case SL::OP_ASSIGN: return "=";
case SL::OP_ADD: return "+";
case SL::OP_SUB: return "-";
case SL::OP_MUL: return "*";
case SL::OP_DIV: return "/";
case SL::OP_ASSIGN_ADD: return "+=";
case SL::OP_ASSIGN_SUB: return "-=";
case SL::OP_ASSIGN_MUL: return "*=";
case SL::OP_ASSIGN_DIV: return "/=";
case SL::OP_NEG: return "-";
case SL::OP_NOT: return "!";
case SL::OP_CMP_EQ: return "==";
case SL::OP_CMP_NEQ: return "!=";
case SL::OP_CMP_LEQ: return "<=";
case SL::OP_CMP_GEQ: return ">=";
case SL::OP_CMP_LESS: return "<";
case SL::OP_CMP_GREATER: return ">";
case SL::OP_CMP_OR: return "||";
case SL::OP_CMP_AND: return "&&";
default: return "";
}
return "";
}
static String dump_node_code(SL::Node *p_node,int p_level) {
String code;
switch(p_node->type) {
case SL::Node::TYPE_PROGRAM: {
SL::ProgramNode *pnode=(SL::ProgramNode*)p_node;
for(Map<StringName,SL::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) {
String ucode="uniform ";
ucode+=_typestr(E->get().type)+"="+String(E->get().default_value)+"\n";
code+=ucode;
}
for(int i=0;i<pnode->functions.size();i++) {
SL::FunctionNode *fnode=pnode->functions[i].function;
String header;
header=_typestr(fnode->return_type)+" "+fnode->name+"(";
for(int i=0;i<fnode->arguments.size();i++) {
if (i>0)
header+=", ";
header+=_typestr(fnode->arguments[i].type)+" "+fnode->arguments[i].name;
}
header+=") {\n";
code+=header;
code+=dump_node_code(fnode->body,p_level+1);
code+="}\n";
}
code+=dump_node_code(pnode->body,p_level);
} break;
case SL::Node::TYPE_FUNCTION: {
} break;
case SL::Node::TYPE_BLOCK: {
SL::BlockNode *bnode=(SL::BlockNode*)p_node;
//variables
for(Map<StringName,SL::DataType>::Element *E=bnode->variables.front();E;E=E->next()) {
code+=_mktab(p_level)+_typestr(E->value())+" "+E->key()+";\n";
}
for(int i=0;i<bnode->statements.size();i++) {
code+=_mktab(p_level)+dump_node_code(bnode->statements[i],p_level)+";\n";
}
} break;
case SL::Node::TYPE_VARIABLE: {
SL::VariableNode *vnode=(SL::VariableNode*)p_node;
code=vnode->name;
} break;
case SL::Node::TYPE_CONSTANT: {
SL::ConstantNode *cnode=(SL::ConstantNode*)p_node;
switch(cnode->datatype) {
case SL::TYPE_BOOL: code=cnode->value.operator bool()?"true":"false"; break;
case SL::TYPE_FLOAT: code=cnode->value; break;
case SL::TYPE_VEC2: { Vector2 v = cnode->value; code="vec2("+rtos(v.x)+", "+rtos(v.y)+")"; } break;
case SL::TYPE_VEC3: { Vector3 v = cnode->value; code="vec3("+rtos(v.x)+", "+rtos(v.y)+", "+rtos(v.z)+")"; } break;
case SL::TYPE_VEC4: { Plane v = cnode->value; code="vec4("+rtos(v.normal.x)+", "+rtos(v.normal.y)+", "+rtos(v.normal.z)+", "+rtos(v.d)+")"; } break;
case SL::TYPE_MAT3: { Matrix3 x = cnode->value; code="mat3( vec3("+rtos(x.get_axis(0).x)+", "+rtos(x.get_axis(0).y)+", "+rtos(x.get_axis(0).z)+"), vec3("+rtos(x.get_axis(1).x)+", "+rtos(x.get_axis(1).y)+", "+rtos(x.get_axis(1).z)+"), vec3("+rtos(x.get_axis(2).x)+", "+rtos(x.get_axis(2).y)+", "+rtos(x.get_axis(2).z)+"))"; } break;
case SL::TYPE_MAT4: { Transform x = cnode->value; code="mat4( vec3("+rtos(x.basis.get_axis(0).x)+", "+rtos(x.basis.get_axis(0).y)+", "+rtos(x.basis.get_axis(0).z)+"), vec3("+rtos(x.basis.get_axis(1).x)+", "+rtos(x.basis.get_axis(1).y)+", "+rtos(x.basis.get_axis(1).z)+"), vec3("+rtos(x.basis.get_axis(2).x)+", "+rtos(x.basis.get_axis(2).y)+", "+rtos(x.basis.get_axis(2).z)+"), vec3("+rtos(x.origin.x)+", "+rtos(x.origin.y)+", "+rtos(x.origin.z)+"))"; } break;
default: code="<error: "+Variant::get_type_name(cnode->value.get_type())+" ("+itos(cnode->datatype)+">";
}
} break;
case SL::Node::TYPE_OPERATOR: {
SL::OperatorNode *onode=(SL::OperatorNode*)p_node;
switch(onode->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:
code=dump_node_code(onode->arguments[0],p_level)+_opstr(onode->op)+dump_node_code(onode->arguments[1],p_level);
break;
case SL::OP_ADD:
case SL::OP_SUB:
case SL::OP_MUL:
case SL::OP_DIV:
case SL::OP_CMP_EQ:
case SL::OP_CMP_NEQ:
case SL::OP_CMP_LEQ:
case SL::OP_CMP_GEQ:
case SL::OP_CMP_LESS:
case SL::OP_CMP_GREATER:
case SL::OP_CMP_OR:
case SL::OP_CMP_AND:
code="("+dump_node_code(onode->arguments[0],p_level)+_opstr(onode->op)+dump_node_code(onode->arguments[1],p_level)+")";
break;
case SL::OP_NEG:
case SL::OP_NOT:
code=_opstr(onode->op)+dump_node_code(onode->arguments[0],p_level);
break;
case SL::OP_CALL:
case SL::OP_CONSTRUCT:
code=dump_node_code(onode->arguments[0],p_level)+"(";
for(int i=1;i<onode->arguments.size();i++) {
if (i>1)
code+=", ";
code+=dump_node_code(onode->arguments[i],p_level);
}
code+=")";
break;
default: {}
}
} break;
case SL::Node::TYPE_CONTROL_FLOW: {
SL::ControlFlowNode *cfnode=(SL::ControlFlowNode*)p_node;
if (cfnode->flow_op==SL::FLOW_OP_IF) {
code+="if ("+dump_node_code(cfnode->statements[0],p_level)+") {\n";
code+=dump_node_code(cfnode->statements[1],p_level+1);
if (cfnode->statements.size()==3) {
code+="} else {\n";
code+=dump_node_code(cfnode->statements[2],p_level+1);
}
code+="}\n";
} else if (cfnode->flow_op==SL::FLOW_OP_RETURN) {
if (cfnode->statements.size()) {
code="return "+dump_node_code(cfnode->statements[0],p_level);
} else {
code="return";
}
}
} break;
case SL::Node::TYPE_MEMBER: {
SL::MemberNode *mnode=(SL::MemberNode*)p_node;
code=dump_node_code(mnode->owner,p_level)+"."+mnode->name;
} break;
}
return code;
}
static Error recreate_code(void *p_str,SL::ProgramNode *p_program) {
print_line("recr");
String *str=(String*)p_str;
*str=dump_node_code(p_program,0);
return OK;
}
MainLoop* test() {
List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
if (cmdlargs.empty()) {
//try editor!
return NULL;
}
String test = cmdlargs.back()->get();
FileAccess *fa = FileAccess::open(test,FileAccess::READ);
if (!fa) {
ERR_FAIL_V(NULL);
}
String code;
while(true) {
CharType c = fa->get_8();
if (fa->eof_reached())
break;
code+=c;
}
int errline;
int errcol;
String error;
print_line(SL::lex_debug(code));
Error err = SL::compile(code,ShaderLanguage::SHADER_MATERIAL_FRAGMENT,NULL,NULL,&error,&errline,&errcol);
if (err) {
print_line("Error: "+itos(errline)+":"+itos(errcol)+" "+error);
return NULL;
}
print_line("Compile OK! - pretty printing");
String rcode;
err = SL::compile(code,ShaderLanguage::SHADER_MATERIAL_FRAGMENT,recreate_code,&rcode,&error,&errline,&errcol);
if (!err) {
print_line(rcode);
}
ShaderCompilerGLES2 comp;
String codeline,globalsline;
SL::VarInfo vi;
vi.name="mongs";
vi.type=SL::TYPE_VEC3;
ShaderCompilerGLES2::Flags fl;
comp.compile(code,ShaderLanguage::SHADER_MATERIAL_FRAGMENT,codeline,globalsline,fl);
return NULL;
}
}

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,15 +26,15 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEST_SHADER_LANG_H
#define TEST_SHADER_LANG_H
#include "core/os/main_loop.h"
#include "os/main_loop.h"
namespace TestShaderLang {
MainLoop *test();
MainLoop* test();
}
#endif // TEST_SHADER_LANG_H

95
bin/tests/test_sound.cpp Normal file
View File

@ -0,0 +1,95 @@
/*************************************************************************/
/* test_sound.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "test_sound.h"
#include "servers/visual_server.h"
#include "os/main_loop.h"
#include "math_funcs.h"
#include "scene/resources/sample.h"
#include "io/resource_loader.h"
#include "print_string.h"
#include "servers/audio_server.h"
#include "os/os.h"
namespace TestSound {
class TestMainLoop : public MainLoop {
bool quit;
Ref<Sample> sample;
public:
virtual void input_event(const InputEvent& p_event) {
}
virtual void request_quit() {
quit=true;
}
virtual void init() {
List<String> cmdline = OS::get_singleton()->get_cmdline_args();
quit=false;
if (cmdline.size()) {
sample=ResourceLoader::load(cmdline.back()->get());
ERR_FAIL_COND(sample.is_null());
print_line("Sample loaded OK");
}
RID voice = AudioServer::get_singleton()->voice_create();
AudioServer::get_singleton()->voice_play( voice, sample->get_rid() );
}
virtual bool idle(float p_time) {
return false;
}
virtual bool iteration(float p_time) {
return quit;
}
virtual void finish() {
}
};
MainLoop* test() {
return memnew( TestMainLoop );
}
}

40
bin/tests/test_sound.h Normal file
View File

@ -0,0 +1,40 @@
/*************************************************************************/
/* test_sound.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 TEST_SOUND_H
#define TEST_SOUND_H
#include "os/main_loop.h"
namespace TestSound {
MainLoop* test();
}
#endif // TEST_SOUND_H

916
bin/tests/test_string.cpp Normal file
View File

@ -0,0 +1,916 @@
/*************************************************************************/
/* test_string.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "ustring.h"
#include <wchar.h>
//#include "math_funcs.h"
#include <stdio.h>
#include "os/os.h"
#include "drivers/trex/regex.h"
#include "test_string.h"
namespace TestString {
bool test_1() {
OS::get_singleton()->print("\n\nTest 1: Assign from cstr\n");
String s = "Hello";
OS::get_singleton()->print("\tExpected: Hello\n");
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
return (wcscmp(s.c_str(),L"Hello")==0);
}
bool test_2() {
OS::get_singleton()->print("\n\nTest 2: Assign from string (operator=)\n");
String s = "Dolly";
String t = s;
OS::get_singleton()->print("\tExpected: Dolly\n");
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
return (wcscmp(t.c_str(),L"Dolly")==0);
}
bool test_3() {
OS::get_singleton()->print("\n\nTest 3: Assign from c-string (copycon)\n");
String s("Sheep");
String t(s);
OS::get_singleton()->print("\tExpected: Sheep\n");
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
return (wcscmp(t.c_str(),L"Sheep")==0);
}
bool test_4() {
OS::get_singleton()->print("\n\nTest 4: Assign from c-widechar (operator=)\n");
String s(L"Give me");
OS::get_singleton()->print("\tExpected: Give me\n");
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
return (wcscmp(s.c_str(),L"Give me")==0);
}
bool test_5() {
OS::get_singleton()->print("\n\nTest 5: Assign from c-widechar (copycon)\n");
String s(L"Wool");
OS::get_singleton()->print("\tExpected: Wool\n");
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
return (wcscmp(s.c_str(),L"Wool")==0);
}
bool test_6() {
OS::get_singleton()->print("\n\nTest 6: comparisons (equal)\n");
String s="Test Compare";
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
if (! ( s=="Test Compare" ) )
return false;
if (! ( s==L"Test Compare" ) )
return false;
if (! ( s==String("Test Compare") ) )
return false;
return true;
}
bool test_7() {
OS::get_singleton()->print("\n\nTest 7: comparisons (unequal)\n");
String s="Test Compare";
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
if (! ( s!="Peanut" ) )
return false;
if (! ( s!=L"Coconut" ) )
return false;
if (! ( s!=String("Butter") ) )
return false;
return true;
}
bool test_8() {
OS::get_singleton()->print("\n\nTest 8: comparisons (operator<)\n");
String s="Bees";
OS::get_singleton()->print("\tComparing to \"Bees\"\n");
if ( ! (s < "Elephant") )
return false;
if ( s < L"Amber" )
return false;
if ( s < String("Beatrix") )
return false;
return true;
}
bool test_9() {
OS::get_singleton()->print("\n\nTest 9: Concatenation\n");
String s;
s+="Have";
s+=' ';
s+='a';
s+=String(" ");
s = s + L"Nice";
s = s + " ";
s = s + String("Day");
OS::get_singleton()->print("\tComparing to \"Have a Nice Day\"\n");
return (s == "Have a Nice Day");
}
bool test_10() {
OS::get_singleton()->print("\n\nTest 10: Misc funcs (size/length/empty/etc)\n");
if (! String("").empty())
return false;
if (String("Mellon").size() != 7)
return false;
if (String("Oranges").length() != 7)
return false;
return true;
}
bool test_11() {
OS::get_singleton()->print("\n\nTest 11: Operator[]\n");
String a="Kugar Sane";
a[0]='S';
a[6]='C';
if (a != "Sugar Cane")
return false;
if (a[1]!='u')
return false;
return true;
}
bool test_12() {
OS::get_singleton()->print("\n\nTest 12: case functions\n");
String a="MoMoNgA";
if (a.to_upper() != "MOMONGA")
return false;
if (a.nocasecmp_to("momonga")!=0)
return false;
return true;
}
bool test_13() {
OS::get_singleton()->print("\n\nTest 13: UTF8\n");
/* how can i embed UTF in here? */
static const CharType ustr[] = { 0x304A , 0x360F, 0x3088, 0x3046, 0 };
// static const wchar_t ustr[] = { 'P', 0xCE, 'p',0xD3, 0 };
String s=ustr;
OS::get_singleton()->print("\tUnicode: %ls\n",ustr);
s.parse_utf8( s.utf8().get_data() );
OS::get_singleton()->print("\tConvert/Parse UTF8: %ls\n",s.c_str());
return (s==ustr);
}
bool test_14() {
OS::get_singleton()->print("\n\nTest 14: ASCII\n");
String s = L"Primero Leche";
OS::get_singleton()->print("\tAscii: %s\n",s.ascii().get_data());
String t=s.ascii().get_data();
return (s==t);
}
bool test_15() {
OS::get_singleton()->print("\n\nTest 15: substr\n");
String s="Killer Baby";
OS::get_singleton()->print("\tsubstr(3,4) of \"%ls\" is \"%ls\"\n",s.c_str(),s.substr(3,4).c_str());
return (s.substr(3,4)=="ler ");
}
bool test_16() {
OS::get_singleton()->print("\n\nTest 16: find\n");
String s="Pretty Woman";
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\t\"tty\" is at %i pos.\n",s.find("tty"));
OS::get_singleton()->print("\t\"Revenge of the Monster Truck\" is at %i pos.\n",s.find("Revenge of the Monster Truck"));
if (s.find("tty")!=3)
return false;
if (s.find("Revenge of the Monster Truck")!=-1)
return false;
return true;
}
bool test_17() {
OS::get_singleton()->print("\n\nTest 17: find no case\n");
String s="Pretty Whale";
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
if (s.findn("WHA")!=7)
return false;
if (s.findn("Revenge of the Monster SawFish")!=-1)
return false;
return true;
}
bool test_18() {
OS::get_singleton()->print("\n\nTest 18: find no case\n");
String s="Pretty Whale";
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
if (s.findn("WHA")!=7)
return false;
if (s.findn("Revenge of the Monster SawFish")!=-1)
return false;
return true;
}
bool test_19() {
OS::get_singleton()->print("\n\nTest 19: Search & replace\n");
String s="Happy Birthday, Anna!";
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
s=s.replace("Birthday","Halloween");
OS::get_singleton()->print("\tReplaced Birthday/Halloween: %ls.\n",s.c_str());
return (s=="Happy Halloween, Anna!");
}
bool test_20() {
OS::get_singleton()->print("\n\nTest 20: Insertion\n");
String s="Who is Frederic?";
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
s=s.insert( s.find("?")," Chopin" );
OS::get_singleton()->print("\tInserted Chopin: %ls.\n",s.c_str());
return (s=="Who is Frederic Chopin?");
}
bool test_21() {
OS::get_singleton()->print("\n\nTest 21: Number -> String\n");
OS::get_singleton()->print("\tPi is %f\n",33.141593);
OS::get_singleton()->print("\tPi String is %ls\n",String::num(3.141593).c_str());
return String::num(3.141593)=="3.141593";
}
bool test_22() {
OS::get_singleton()->print("\n\nTest 22: String -> Int\n");
static const char* nums[4]={ "1237461283", "- 22", "0", " - 1123412" };
static const int num[4]={ 1237461283, -22, 0, -1123412 };
for (int i=0;i<4;i++) {
OS::get_singleton()->print("\tString: \"%s\" as Int is %i\n",nums[i],String(nums[i]).to_int());
if (String(nums[i]).to_int()!=num[i])
return false;
}
return true;
}
bool test_23() {
OS::get_singleton()->print("\n\nTest 23: String -> Float\n");
static const char* nums[4]={ "-12348298412.2", "0.05", "2.0002", " -0.0001" };
static const double num[4]={ -12348298412.2, 0.05, 2.0002, -0.0001 };
for (int i=0;i<4;i++) {
OS::get_singleton()->print("\tString: \"%s\" as Float is %f\n",nums[i],String(nums[i]).to_double());
if ( ABS(String(nums[i]).to_double()-num[i])>0.00001)
return false;
}
return true;
}
bool test_24() {
OS::get_singleton()->print("\n\nTest 24: Slicing\n");
String s="Mars,Jupiter,Saturn,Uranus";
const char*slices[4]={"Mars","Jupiter","Saturn","Uranus"};
OS::get_singleton()->print("\tSlicing \"%ls\" by \"%s\"..\n",s.c_str(),",");
for (int i=0;i<s.get_slice_count(",");i++) {
OS::get_singleton()->print("\t\t%i- %ls\n",i+1,s.get_slice(",",i).c_str());
if (s.get_slice(",",i)!=slices[i])
return false;
}
return true;
}
bool test_25() {
OS::get_singleton()->print("\n\nTest 25: Erasing\n");
String s="Josephine is such a cute girl!";
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\tRemoving \"cute\"\n");
s.erase(s.find("cute "),String("cute ").length());
OS::get_singleton()->print("\tResult: %ls\n",s.c_str());
return (s=="Josephine is such a girl!");
}
bool test_26() {
OS::get_singleton()->print("\n\nTest 26: RegEx\n");
RegEx regexp("(.*):(.*)");
List<String> captures;
bool match = regexp.match("name:password", &captures);
printf("\tmatch: %s\n", match?"true":"false");
printf("\t%i captures:\n", captures.size());
List<String>::Element *I = captures.front();
while (I) {
printf("%ls\n", I->get().c_str());
I = I->next();
};
return captures.size();
};
struct test_27_data {
char const * data;
char const * begin;
bool expected;
};
bool test_27() {
OS::get_singleton()->print("\n\nTest 27: begins_with\n");
test_27_data tc[] = {
{"res://foobar", "res://", true},
{"res", "res://", false},
{"abc", "abc", true}
};
size_t count = sizeof(tc) / sizeof(tc[0]);
bool state = true;
for (size_t i = 0;state && i < count; ++i) {
String s = tc[i].data;
state = s.begins_with(tc[i].begin) == tc[i].expected;
if (state) {
String sb = tc[i].begin;
state = s.begins_with(sb) == tc[i].expected;
}
if (!state) {
OS::get_singleton()->print("\n\t Failure on:\n\t\tstring: ", tc[i].data, "\n\t\tbegin: ", tc[i].begin, "\n\t\texpected: ", tc[i].expected ? "true" : "false", "\n");
break;
}
};
return state;
};
bool test_28() {
OS::get_singleton()->print("\n\nTest 28: sprintf\n");
bool success, state = true;
char output_format[] = "\tTest:\t%ls => %ls (%s)\n";
String format, output;
Array args;
bool error;
// %%
format = "fish %% frog";
args.clear();
output = format.sprintf(args, &error);
success = (output == String("fish % frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
//////// INTS
// Int
format = "fish %d frog";
args.clear();
args.push_back(5);
output = format.sprintf(args, &error);
success = (output == String("fish 5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Int left padded with zeroes.
format = "fish %05d frog";
args.clear();
args.push_back(5);
output = format.sprintf(args, &error);
success = (output == String("fish 00005 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Int left padded with spaces.
format = "fish %5d frog";
args.clear();
args.push_back(5);
output = format.sprintf(args, &error);
success = (output == String("fish 5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Int right padded with spaces.
format = "fish %-5d frog";
args.clear();
args.push_back(5);
output = format.sprintf(args, &error);
success = (output == String("fish 5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Int with sign (positive).
format = "fish %+d frog";
args.clear();
args.push_back(5);
output = format.sprintf(args, &error);
success = (output == String("fish +5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Negative int.
format = "fish %d frog";
args.clear();
args.push_back(-5);
output = format.sprintf(args, &error);
success = (output == String("fish -5 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Hex (lower)
format = "fish %x frog";
args.clear();
args.push_back(45);
output = format.sprintf(args, &error);
success = (output == String("fish 2d frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Hex (upper)
format = "fish %X frog";
args.clear();
args.push_back(45);
output = format.sprintf(args, &error);
success = (output == String("fish 2D frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Octal
format = "fish %o frog";
args.clear();
args.push_back(99);
output = format.sprintf(args, &error);
success = (output == String("fish 143 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
////// REALS
// Real
format = "fish %f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Real left-padded
format = "fish %11f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Real right-padded
format = "fish %-11f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Real given int.
format = "fish %f frog";
args.clear();
args.push_back(99);
output = format.sprintf(args, &error);
success = (output == String("fish 99.000000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Real with sign (positive).
format = "fish %+f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args, &error);
success = (output == String("fish +99.990000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Real with 1 decimals.
format = "fish %.1f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args, &error);
success = (output == String("fish 100.0 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Real with 12 decimals.
format = "fish %.12f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args, &error);
success = (output == String("fish 99.990000000000 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Real with no decimals.
format = "fish %.f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args, &error);
success = (output == String("fish 100 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
/////// Strings.
// String
format = "fish %s frog";
args.clear();
args.push_back("cheese");
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// String left-padded
format = "fish %10s frog";
args.clear();
args.push_back("cheese");
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// String right-padded
format = "fish %-10s frog";
args.clear();
args.push_back("cheese");
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
///// Characters
// Character as string.
format = "fish %c frog";
args.clear();
args.push_back("A");
output = format.sprintf(args, &error);
success = (output == String("fish A frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Character as int.
format = "fish %c frog";
args.clear();
args.push_back(65);
output = format.sprintf(args, &error);
success = (output == String("fish A frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
///// Dynamic width
// String dynamic width
format = "fish %*s frog";
args.clear();
args.push_back(10);
args.push_back("cheese");
output = format.sprintf(args, &error);
success = (output == String("fish cheese frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Int dynamic width
format = "fish %*d frog";
args.clear();
args.push_back(10);
args.push_back(99);
output = format.sprintf(args, &error);
success = (output == String("fish 99 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Float dynamic width
format = "fish %*.*f frog";
args.clear();
args.push_back(10);
args.push_back(3);
args.push_back(99.99);
output = format.sprintf(args, &error);
success = (output == String("fish 99.990 frog") && !error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
///// Errors
// More formats than arguments.
format = "fish %s %s frog";
args.clear();
args.push_back("cheese");
output = format.sprintf(args, &error);
success = (output == "not enough arguments for format string" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// More arguments than formats.
format = "fish %s frog";
args.clear();
args.push_back("hello");
args.push_back("cheese");
output = format.sprintf(args, &error);
success = (output == "not all arguments converted during string formatting" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Incomplete format.
format = "fish %10";
args.clear();
args.push_back("cheese");
output = format.sprintf(args, &error);
success = (output == "incomplete format" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Bad character in format string
format = "fish %&f frog";
args.clear();
args.push_back("cheese");
output = format.sprintf(args, &error);
success = (output == "unsupported format character" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Too many decimals.
format = "fish %2.2.2f frog";
args.clear();
args.push_back(99.99);
output = format.sprintf(args, &error);
success = (output == "too many decimal points in format" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// * not a number
format = "fish %*f frog";
args.clear();
args.push_back("cheese");
args.push_back(99.99);
output = format.sprintf(args, &error);
success = (output == "* wants number" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Character too long.
format = "fish %c frog";
args.clear();
args.push_back("sc");
output = format.sprintf(args, &error);
success = (output == "%c requires number or single-character string" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
// Character bad type.
format = "fish %c frog";
args.clear();
args.push_back(Array());
output = format.sprintf(args, &error);
success = (output == "%c requires number or single-character string" && error);
OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
if (!success) state = false;
return state;
}
typedef bool (*TestFunc)(void);
TestFunc test_funcs[] = {
test_1,
test_2,
test_3,
test_4,
test_5,
test_6,
test_7,
test_8,
test_9,
test_10,
test_11,
test_12,
test_13,
test_14,
test_15,
test_16,
test_17,
test_18,
test_19,
test_20,
test_21,
test_22,
test_23,
test_24,
test_25,
test_26,
test_27,
test_28,
0
};
MainLoop* test() {
/** A character length != wchar_t may be forced, so the tests wont work */
ERR_FAIL_COND_V( sizeof(CharType) != sizeof(wchar_t), NULL );
int count=0;
int passed=0;
while(true) {
if (!test_funcs[count])
break;
bool pass=test_funcs[count]();
if (pass)
passed++;
OS::get_singleton()->print("\t%s\n",pass?"PASS":"FAILED");
count++;
}
OS::get_singleton()->print("\n\n\n");
OS::get_singleton()->print("*************\n");
OS::get_singleton()->print("***TOTALS!***\n");
OS::get_singleton()->print("*************\n");
OS::get_singleton()->print("Passed %i of %i tests\n",count,passed);
return NULL;
}
}

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,16 +26,19 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef TEST_STRING_H
#define TEST_STRING_H
#include "core/os/main_loop.h"
#include "core/ustring.h"
#include "ustring.h"
#include "os/main_loop.h"
namespace TestString {
MainLoop *test();
MainLoop* test();
}
#endif

View File

@ -1,97 +0,0 @@
import sys
if sys.version_info < (3,):
def isbasestring(s):
return isinstance(s, basestring)
def open_utf8(filename, mode):
return open(filename, mode)
def byte_to_str(x):
return str(ord(x))
import cStringIO
def StringIO():
return cStringIO.StringIO()
def encode_utf8(x):
return x
def decode_utf8(x):
return x
def iteritems(d):
return d.iteritems()
def itervalues(d):
return d.itervalues()
def escape_string(s):
if isinstance(s, unicode):
s = s.encode("ascii")
result = ""
for c in s:
if not (32 <= ord(c) < 127) or c in ("\\", '"'):
result += "\\%03o" % ord(c)
else:
result += c
return result
def qualname(obj):
# Not properly equivalent to __qualname__ in py3, but it doesn't matter.
return obj.__name__
else:
def isbasestring(s):
return isinstance(s, (str, bytes))
def open_utf8(filename, mode):
return open(filename, mode, encoding="utf-8")
def byte_to_str(x):
return str(x)
import io
def StringIO():
return io.StringIO()
import codecs
def encode_utf8(x):
return codecs.utf_8_encode(x)[0]
def decode_utf8(x):
return codecs.utf_8_decode(x)[0]
def iteritems(d):
return iter(d.items())
def itervalues(d):
return iter(d.values())
def charcode_to_c_escapes(c):
rev_result = []
while c >= 256:
c, low = (c // 256, c % 256)
rev_result.append("\\%03o" % low)
rev_result.append("\\%03o" % c)
return "".join(reversed(rev_result))
def escape_string(s):
result = ""
if isinstance(s, str):
s = s.encode("utf-8")
for c in s:
if not (32 <= c < 127) or c in (ord("\\"), ord('"')):
result += charcode_to_c_escapes(c)
else:
result += chr(c)
return result
def qualname(obj):
return obj.__qualname__

View File

@ -1,197 +1,67 @@
#!/usr/bin/env python
Import('env')
Import("env")
import core_builders
import make_binders
from platform_methods import run_in_subprocess
env.core_sources = []
env.core_sources=[]
# Generate AES256 script encryption key
gd_call=""
gd_inc=""
for x in env.global_defaults:
env.core_sources.append("#platform/"+x+"/globals/global_defaults.cpp")
gd_inc+='#include "platform/'+x+'/globals/global_defaults.h"\n'
gd_call+="\tregister_"+x+"_global_defaults();\n"
gd_cpp='#include "globals.h"\n'
gd_cpp+=gd_inc
gd_cpp+="void Globals::register_global_defaults() {\n"+gd_call+"\n}\n"
f = open("global_defaults.cpp","wb")
f.write(gd_cpp)
f.close()
import os
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"
if "SCRIPT_AES256_ENCRYPTION_KEY" in os.environ:
e = os.environ["SCRIPT_AES256_ENCRYPTION_KEY"]
txt = ""
ec_valid = True
if len(e) != 64:
ec_valid = False
else:
if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ):
e=os.environ["SCRIPT_AES256_ENCRYPTION_KEY"]
txt = ""
ec_valid=True
if (len(e)!=64):
ec_valid=False
else:
for i in range(len(e) >> 1):
if i > 0:
txt += ","
txts = "0x" + e[i * 2 : i * 2 + 2]
try:
int(txts, 16)
except Exception:
ec_valid = False
txt += txts
if not ec_valid:
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)
for i in range(len(e)>>1):
if (i>0):
txt+=","
txts="0x"+e[i*2:i*2+2]
try:
int(txts,16)
except:
ec_valid=False
txt+=txts
if (not ec_valid):
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)
# NOTE: It is safe to generate this file here, since this is still executed serially
with open("script_encryption_key.gen.cpp", "w") as f:
f.write('#include "core/project_settings.h"\nuint8_t script_encryption_key[32]={' + txt + "};\n")
f = open("script_encryption_key.cpp", "wb")
f.write("#include \"globals.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
f.close()
# Add required thirdparty code.
thirdparty_obj = []
env_thirdparty = env.Clone()
env_thirdparty.disable_warnings()
# Misc thirdparty code: header paths are hardcoded, we don't need to append
# to the include path (saves a few chars on the compiler invocation for touchy MSVC...)
thirdparty_misc_dir = "#thirdparty/misc/"
thirdparty_misc_sources = [
# C sources
"fastlz.c",
"smaz.c",
# C++ sources
"hq2x.cpp",
"pcg.cpp",
"triangulator.cpp",
"clipper.cpp",
]
thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_misc_sources)
# Zlib library, can be unbundled
if env["builtin_zlib"]:
thirdparty_zlib_dir = "#thirdparty/zlib/"
thirdparty_zlib_sources = [
"adler32.c",
"compress.c",
"crc32.c",
"deflate.c",
"infback.c",
"inffast.c",
"inflate.c",
"inftrees.c",
"trees.c",
"uncompr.c",
"zutil.c",
]
thirdparty_zlib_sources = [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources]
env_thirdparty.Prepend(CPPPATH=[thirdparty_zlib_dir])
# Needs to be available in main env too
env.Prepend(CPPPATH=[thirdparty_zlib_dir])
if env["target"] == "debug":
env_thirdparty.Append(CPPDEFINES=["ZLIB_DEBUG"])
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_zlib_sources)
# Minizip library, could be unbundled in theory
# However, our version has some custom modifications, so it won't compile with the system one
thirdparty_minizip_dir = "#thirdparty/minizip/"
thirdparty_minizip_sources = [
"ioapi.c",
"unzip.c",
"zip.c",
]
thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources]
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_minizip_sources)
# Zstd library, can be unbundled in theory
# though we currently use some private symbols
# https://github.com/godotengine/godot/issues/17374
if env["builtin_zstd"]:
thirdparty_zstd_dir = "#thirdparty/zstd/"
thirdparty_zstd_sources = [
"common/debug.c",
"common/entropy_common.c",
"common/error_private.c",
"common/fse_decompress.c",
"common/pool.c",
"common/threading.c",
"common/xxhash.c",
"common/zstd_common.c",
"compress/fse_compress.c",
"compress/hist.c",
"compress/huf_compress.c",
"compress/zstd_compress.c",
"compress/zstd_double_fast.c",
"compress/zstd_fast.c",
"compress/zstd_lazy.c",
"compress/zstd_ldm.c",
"compress/zstd_opt.c",
"compress/zstdmt_compress.c",
"compress/zstd_compress_literals.c",
"compress/zstd_compress_sequences.c",
"compress/zstd_compress_superblock.c",
"decompress/huf_decompress.c",
"decompress/zstd_ddict.c",
"decompress/zstd_decompress_block.c",
"decompress/zstd_decompress.c",
]
thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources]
env_thirdparty.Prepend(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"])
env_thirdparty.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"])
env.Prepend(CPPPATH=thirdparty_zstd_dir)
# Also needed in main env includes will trigger warnings
env.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"])
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_zstd_sources)
env.add_source_files(env.core_sources,"*.cpp")
env.core_sources += thirdparty_obj
Export('env')
import make_binders
env.Command(['method_bind.inc','method_bind_ext.inc'], 'make_binders.py', make_binders.run)
# Godot source files
SConscript('os/SCsub');
SConscript('math/SCsub');
SConscript('io/SCsub');
SConscript('bind/SCsub');
env.add_source_files(env.core_sources, "*.cpp")
lib = env.Library("core",env.core_sources)
# Certificates
env.Depends(
"#core/io/certs_compressed.gen.h",
["#thirdparty/certs/ca-certificates.crt", env.Value(env["builtin_certs"]), env.Value(env["system_certs_path"])],
)
env.CommandNoCache(
"#core/io/certs_compressed.gen.h",
"#thirdparty/certs/ca-certificates.crt",
run_in_subprocess(core_builders.make_certs_header),
)
# Make binders
env.CommandNoCache(
["method_bind.gen.inc", "method_bind_ext.gen.inc", "method_bind_free_func.gen.inc"],
"make_binders.py",
run_in_subprocess(make_binders.run),
)
# Authors
env.Depends("#core/authors.gen.h", "../AUTHORS.md")
env.CommandNoCache("#core/authors.gen.h", "../AUTHORS.md", run_in_subprocess(core_builders.make_authors_header))
# Donors
env.Depends("#core/donors.gen.h", "../DONORS.md")
env.CommandNoCache("#core/donors.gen.h", "../DONORS.md", run_in_subprocess(core_builders.make_donors_header))
# License
env.Depends("#core/license.gen.h", ["../COPYRIGHT.txt", "../LICENSE.txt"])
env.CommandNoCache(
"#core/license.gen.h", ["../COPYRIGHT.txt", "../LICENSE.txt"], run_in_subprocess(core_builders.make_license_header)
)
# Chain load SCsubs
SConscript("os/SCsub")
SConscript("math/SCsub")
SConscript("crypto/SCsub")
SConscript("io/SCsub")
SConscript("bind/SCsub")
# Build it all as a library
lib = env.add_library("core", env.core_sources)
env.Prepend(LIBS=[lib])
# Needed to force rebuilding the core files when the thirdparty code is updated.
env.Depends(lib, thirdparty_obj)

198
core/allocators.h Normal file
View File

@ -0,0 +1,198 @@
/*************************************************************************/
/* allocators.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 ALLOCATORS_H
#define ALLOCATORS_H
#include "os/memory.h"
template<int PREALLOC_COUNT=64, int MAX_HANDS=8>
class BalloonAllocator {
enum {
USED_FLAG=(1<<30),
USED_MASK=USED_FLAG-1
};
struct Balloon {
Balloon *next;
Balloon *prev;
uint32_t hand;
};
struct Hand {
int used;
int allocated;
Balloon *first;
Balloon *last;
};
Hand hands[MAX_HANDS];
public:
void* alloc(size_t p_size) {
size_t max=(1<<MAX_HANDS);
ERR_FAIL_COND_V( p_size>max, NULL );
unsigned int hand=0;
while(p_size>(size_t)(1<<hand)) ++hand;
Hand &h=hands[hand];
if (h.used==h.allocated) {
for(int i=0;i<PREALLOC_COUNT;i++) {
Balloon *b = (Balloon*)memalloc(sizeof(Balloon)+(1<<hand));
b->hand=hand;
if (h.last) {
b->prev=h.last;
h.last->next=b;
h.last=b;
} else {
b->prev=NULL;
h.last=b;
h.first=b;
}
}
h.last->next=NULL;
h.allocated+=PREALLOC_COUNT;
}
Balloon *pick=h.last;
ERR_FAIL_COND_V( (pick->hand&USED_FLAG), NULL );
// remove last
h.last=h.last->prev;
h.last->next=NULL;
pick->next=h.first;
h.first->prev=pick;
pick->prev=NULL;
h.first=pick;
h.used++;
pick->hand|=USED_FLAG;
return (void*)(pick+1);
}
void free(void* p_ptr) {
Balloon *b=(Balloon*)p_ptr;
b-=1;
ERR_FAIL_COND(!(b->hand&USED_FLAG) );
b->hand=b->hand&USED_MASK; // not used
int hand=b->hand;
Hand &h=hands[hand];
if (b==h.first)
h.first=b->next;
if (b->prev)
b->prev->next=b->next;
if (b->next)
b->next->prev=b->prev;
if (h.last!=b) {
h.last->next=b;
b->prev=h.last;
b->next=NULL;
h.last=b;
}
h.used--;
if (h.used<=(h.allocated-(PREALLOC_COUNT*2))) { // this is done to ensure no alloc/free is done constantly
for(int i=0;i<PREALLOC_COUNT;i++) {
ERR_CONTINUE( h.last->hand& USED_FLAG );
Balloon *new_last=h.last->prev;
if (new_last)
new_last->next=NULL;
memfree( h.last );
h.last=new_last;
}
h.allocated-=PREALLOC_COUNT;
}
}
BalloonAllocator() {
for(int i=0;i<MAX_HANDS;i++) {
hands[i].allocated=0;
hands[i].used=0;
hands[i].first=NULL;
hands[i].last=NULL;
}
}
void clear() {
for(int i=0;i<MAX_HANDS;i++) {
while(hands[i].first) {
Balloon *b=hands[i].first;
hands[i].first=b->next;
memfree(b);
}
hands[i].allocated=0;
hands[i].used=0;
hands[i].first=NULL;
hands[i].last=NULL;
}
}
~BalloonAllocator() {
clear();
}
};
#endif // ALLOCATORS_H

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,36 +26,48 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "array.h"
#include "vector.h"
#include "hashfuncs.h"
#include "variant.h"
#include "object.h"
#include "core/hashfuncs.h"
#include "core/object.h"
#include "core/variant.h"
#include "core/vector.h"
struct ArrayPrivate {
class ArrayPrivate {
public:
SafeRefCount refcount;
Vector<Variant> array;
bool shared;
};
void Array::_ref(const Array &p_from) const {
void Array::_ref(const Array& p_from) const {
ArrayPrivate *_fp = p_from._p;
ERR_FAIL_COND(!_fp); // should NOT happen.
if (_fp == _p)
return; // whatever it is, nothing to do here move along
return; //wathever it is, nothing to do here move along
bool success = _fp->refcount.ref();
ERR_FAIL_COND(!success); // should really not happen either
ERR_FAIL_COND(!success); //should really not happen either
_unref();
_p = p_from._p;
if (_fp->shared) {
_p = p_from._p;
} else {
_p = memnew( ArrayPrivate );
_p->shared=false;
_p->refcount.init();
_p->array=_fp->array;
if (_fp->refcount.unref())
memdelete(_fp);
}
}
void Array::_unref() const {
@ -67,19 +78,21 @@ void Array::_unref() const {
if (_p->refcount.unref()) {
memdelete(_p);
}
_p = NULL;
_p=NULL;
}
Variant &Array::operator[](int p_idx) {
return _p->array.write[p_idx];
}
const Variant &Array::operator[](int p_idx) const {
Variant& Array::operator[](int p_idx) {
return _p->array[p_idx];
}
const Variant& Array::operator[](int p_idx) const {
return _p->array[p_idx];
}
int Array::size() const {
return _p->array.size();
@ -93,112 +106,53 @@ void Array::clear() {
_p->array.clear();
}
bool Array::operator==(const Array &p_array) const {
bool Array::is_shared() const {
return _p == p_array._p;
return _p->shared;
}
bool Array::operator==(const Array& p_array) const {
return _p==p_array._p;
}
uint32_t Array::hash() const {
uint32_t h = hash_djb2_one_32(0);
uint32_t h=hash_djb2_one_32(0);
for (int i = 0; i < _p->array.size(); i++) {
for (int i=0;i<_p->array.size();i++) {
h = hash_djb2_one_32(_p->array[i].hash(), h);
h = hash_djb2_one_32( _p->array[i].hash(), h);
}
return h;
}
void Array::operator=(const Array &p_array) {
void Array::operator=(const Array& p_array) {
_ref(p_array);
}
void Array::push_back(const Variant &p_value) {
void Array::push_back(const Variant& p_value) {
_p->array.push_back(p_value);
}
void Array::append_array(const Array &p_array) {
_p->array.append_array(p_array._p->array);
}
Error Array::resize(int p_new_size) {
return _p->array.resize(p_new_size);
}
void Array::insert(int p_pos, const Variant &p_value) {
void Array::insert(int p_pos, const Variant& p_value) {
_p->array.insert(p_pos, p_value);
_p->array.insert(p_pos,p_value);
}
void Array::erase(const Variant &p_value) {
void Array::erase(const Variant& p_value) {
_p->array.erase(p_value);
}
Variant Array::front() const {
ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array.");
return operator[](0);
}
int Array::find(const Variant& p_value) const {
Variant Array::back() const {
ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array.");
return operator[](_p->array.size() - 1);
}
int Array::find(const Variant &p_value, int p_from) const {
return _p->array.find(p_value, p_from);
}
int Array::rfind(const Variant &p_value, int p_from) const {
if (_p->array.size() == 0)
return -1;
if (p_from < 0) {
// Relative offset from the end
p_from = _p->array.size() + p_from;
}
if (p_from < 0 || p_from >= _p->array.size()) {
// Limit to array boundaries
p_from = _p->array.size() - 1;
}
for (int i = p_from; i >= 0; i--) {
if (_p->array[i] == p_value) {
return i;
}
}
return -1;
}
int Array::find_last(const Variant &p_value) const {
return rfind(p_value);
}
int Array::count(const Variant &p_value) const {
if (_p->array.size() == 0)
return 0;
int amount = 0;
for (int i = 0; i < _p->array.size(); i++) {
if (_p->array[i] == p_value) {
amount++;
}
}
return amount;
}
bool Array::has(const Variant &p_value) const {
return _p->array.find(p_value, 0) != -1;
return _p->array.find(p_value);
}
void Array::remove(int p_pos) {
@ -206,93 +160,33 @@ void Array::remove(int p_pos) {
_p->array.remove(p_pos);
}
void Array::set(int p_idx, const Variant &p_value) {
operator[](p_idx) = p_value;
void Array::set(int p_idx,const Variant& p_value) {
operator[](p_idx)=p_value;
}
const Variant &Array::get(int p_idx) const {
const Variant& Array::get(int p_idx) const {
return operator[](p_idx);
}
Array Array::duplicate(bool p_deep) const {
Array new_arr;
int element_count = size();
new_arr.resize(element_count);
for (int i = 0; i < element_count; i++) {
new_arr[i] = p_deep ? get(i).duplicate(p_deep) : get(i);
}
return new_arr;
}
int Array::_clamp_slice_index(int p_index) const {
int arr_size = size();
int fixed_index = CLAMP(p_index, -arr_size, arr_size - 1);
if (fixed_index < 0) {
fixed_index = arr_size + fixed_index;
}
return fixed_index;
}
Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // like python, but inclusive on upper bound
Array new_arr;
ERR_FAIL_COND_V_MSG(p_step == 0, new_arr, "Array slice step size cannot be zero.");
if (empty()) // Don't try to slice empty arrays.
return new_arr;
if (p_step > 0) {
if (p_begin >= size() || p_end < -size())
return new_arr;
} else { // p_step < 0
if (p_begin < -size() || p_end >= size())
return new_arr;
}
int begin = _clamp_slice_index(p_begin);
int end = _clamp_slice_index(p_end);
int new_arr_size = MAX(((end - begin + p_step) / p_step), 0);
new_arr.resize(new_arr_size);
if (p_step > 0) {
int dest_idx = 0;
for (int idx = begin; idx <= end; idx += p_step) {
ERR_FAIL_COND_V_MSG(dest_idx < 0 || dest_idx >= new_arr_size, Array(), "Bug in Array slice()");
new_arr[dest_idx++] = p_deep ? get(idx).duplicate(p_deep) : get(idx);
}
} else { // p_step < 0
int dest_idx = 0;
for (int idx = begin; idx >= end; idx += p_step) {
ERR_FAIL_COND_V_MSG(dest_idx < 0 || dest_idx >= new_arr_size, Array(), "Bug in Array slice()");
new_arr[dest_idx++] = p_deep ? get(idx).duplicate(p_deep) : get(idx);
}
}
return new_arr;
}
struct _ArrayVariantSort {
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
bool valid = false;
_FORCE_INLINE_ bool operator()(const Variant& p_l, const Variant& p_r) const {
bool valid=false;
Variant res;
Variant::evaluate(Variant::OP_LESS, p_l, p_r, res, valid);
Variant::evaluate(Variant::OP_LESS,p_l,p_r,res,valid);
if (!valid)
res = false;
res=false;
return res;
}
};
Array &Array::sort() {
void Array::sort() {
_p->array.sort_custom<_ArrayVariantSort>();
return *this;
}
struct _ArrayVariantSortCustom {
@ -300,176 +194,46 @@ struct _ArrayVariantSortCustom {
Object *obj;
StringName func;
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
_FORCE_INLINE_ bool operator()(const Variant& p_l, const Variant& p_r) const {
const Variant *args[2] = { &p_l, &p_r };
const Variant*args[2]={&p_l,&p_r};
Variant::CallError err;
bool res = obj->call(func, args, 2, err);
if (err.error != Variant::CallError::CALL_OK)
res = false;
bool res = obj->call(func,args,2,err);
if (err.error!=Variant::CallError::CALL_OK)
res=false;
return res;
}
};
Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
void Array::sort_custom(Object *p_obj,const StringName& p_function){
ERR_FAIL_NULL_V(p_obj, *this);
ERR_FAIL_NULL(p_obj);
SortArray<Variant,_ArrayVariantSortCustom> avs;
avs.compare.obj=p_obj;
avs.compare.func=p_function;
avs.sort(_p->array.ptr(),_p->array.size());
SortArray<Variant, _ArrayVariantSortCustom, true> avs;
avs.compare.obj = p_obj;
avs.compare.func = p_function;
avs.sort(_p->array.ptrw(), _p->array.size());
return *this;
}
void Array::shuffle() {
const int n = _p->array.size();
if (n < 2)
return;
Variant *data = _p->array.ptrw();
for (int i = n - 1; i >= 1; i--) {
const int j = Math::rand() % (i + 1);
const Variant tmp = data[j];
data[j] = data[i];
data[i] = tmp;
}
}
template <typename Less>
_FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value, bool p_before, const Less &p_less) {
int lo = 0;
int hi = p_array.size();
if (p_before) {
while (lo < hi) {
const int mid = (lo + hi) / 2;
if (p_less(p_array.get(mid), p_value)) {
lo = mid + 1;
} else {
hi = mid;
}
}
} else {
while (lo < hi) {
const int mid = (lo + hi) / 2;
if (p_less(p_value, p_array.get(mid))) {
hi = mid;
} else {
lo = mid + 1;
}
}
}
return lo;
}
int Array::bsearch(const Variant &p_value, bool p_before) {
return bisect(_p->array, p_value, p_before, _ArrayVariantSort());
}
int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) {
ERR_FAIL_NULL_V(p_obj, 0);
_ArrayVariantSortCustom less;
less.obj = p_obj;
less.func = p_function;
return bisect(_p->array, p_value, p_before, less);
}
Array &Array::invert() {
void Array::invert(){
_p->array.invert();
return *this;
}
void Array::push_front(const Variant &p_value) {
_p->array.insert(0, p_value);
}
Variant Array::pop_back() {
Array::Array(const Array& p_from) {
if (!_p->array.empty()) {
int n = _p->array.size() - 1;
Variant ret = _p->array.get(n);
_p->array.resize(n);
return ret;
}
return Variant();
}
Variant Array::pop_front() {
if (!_p->array.empty()) {
Variant ret = _p->array.get(0);
_p->array.remove(0);
return ret;
}
return Variant();
}
Variant Array::min() const {
Variant minval;
for (int i = 0; i < size(); i++) {
if (i == 0) {
minval = get(i);
} else {
bool valid;
Variant ret;
Variant test = get(i);
Variant::evaluate(Variant::OP_LESS, test, minval, ret, valid);
if (!valid) {
return Variant(); //not a valid comparison
}
if (bool(ret)) {
//is less
minval = test;
}
}
}
return minval;
}
Variant Array::max() const {
Variant maxval;
for (int i = 0; i < size(); i++) {
if (i == 0) {
maxval = get(i);
} else {
bool valid;
Variant ret;
Variant test = get(i);
Variant::evaluate(Variant::OP_GREATER, test, maxval, ret, valid);
if (!valid) {
return Variant(); //not a valid comparison
}
if (bool(ret)) {
//is less
maxval = test;
}
}
}
return maxval;
}
const void *Array::id() const {
return _p->array.ptr();
}
Array::Array(const Array &p_from) {
_p = NULL;
_p=NULL;
_ref(p_from);
}
Array::Array(bool p_shared) {
Array::Array() {
_p = memnew(ArrayPrivate);
_p = memnew( ArrayPrivate );
_p->refcount.init();
_p->shared=p_shared;
}
Array::~Array() {

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,12 +26,10 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef ARRAY_H
#define ARRAY_H
#include "core/typedefs.h"
#include "typedefs.h"
class Variant;
class ArrayPrivate;
class Object;
@ -41,69 +38,47 @@ class StringName;
class Array {
mutable ArrayPrivate *_p;
void _ref(const Array &p_from) const;
void _ref(const Array& p_from) const;
void _unref() const;
inline int _clamp_slice_index(int p_index) const;
public:
Variant &operator[](int p_idx);
const Variant &operator[](int p_idx) const;
void set(int p_idx, const Variant &p_value);
const Variant &get(int p_idx) const;
Variant& operator[](int p_idx);
const Variant& operator[](int p_idx) const;
void set(int p_idx,const Variant& p_value);
const Variant& get(int p_idx) const;
int size() const;
bool empty() const;
void clear();
bool operator==(const Array &p_array) const;
bool is_shared() const;
bool operator==(const Array& p_array) const;
uint32_t hash() const;
void operator=(const Array &p_array);
void operator=(const Array& p_array);
void push_back(const Variant &p_value);
_FORCE_INLINE_ void append(const Variant &p_value) { push_back(p_value); } //for python compatibility
void append_array(const Array &p_array);
void push_back(const Variant& p_value);
_FORCE_INLINE_ void append(const Variant& p_value) { push_back(p_value); } //for python compatibility
Error resize(int p_new_size);
void insert(int p_pos, const Variant &p_value);
void insert(int p_pos, const Variant& p_value);
void remove(int p_pos);
Variant front() const;
Variant back() const;
void sort();
void sort_custom(Object *p_obj,const StringName& p_function);
void invert();
Array &sort();
Array &sort_custom(Object *p_obj, const StringName &p_function);
void shuffle();
int bsearch(const Variant &p_value, bool p_before = true);
int bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before = true);
Array &invert();
int find(const Variant& p_value) const;
int find(const Variant &p_value, int p_from = 0) const;
int rfind(const Variant &p_value, int p_from = -1) const;
int find_last(const Variant &p_value) const;
int count(const Variant &p_value) const;
bool has(const Variant &p_value) const;
void erase(const Variant& p_value);
void erase(const Variant &p_value);
void push_front(const Variant &p_value);
Variant pop_back();
Variant pop_front();
Array duplicate(bool p_deep = false) const;
Array slice(int p_begin, int p_end, int p_step = 1, bool p_deep = false) const;
Variant min() const;
Variant max() const;
const void *id() const;
Array(const Array &p_from);
Array();
Array(const Array& p_from);
Array(bool p_shared=false);
~Array();
};
#endif // ARRAY_H

35
core/balloon_allocator.h Normal file
View File

@ -0,0 +1,35 @@
/*************************************************************************/
/* balloon_allocator.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 BALLOON_ALLOCATOR_H
#define BALLOON_ALLOCATOR_H
#include "os/memory.h"
#include "allocators.h"
#endif // BALLOON_ALLOCATOR_H

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python
Import('env')
env.add_source_files(env.core_sources,"*.cpp")
Export('env')
Import("env")
env.add_source_files(env.core_sources, "*.cpp")

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,432 +0,0 @@
/*************************************************************************/
/* class_db.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 CLASS_DB_H
#define CLASS_DB_H
#include "core/method_bind.h"
#include "core/object.h"
#include "core/print_string.h"
/** To bind more then 6 parameters include this:
* #include "core/method_bind_ext.gen.inc"
*/
#define DEFVAL(m_defval) (m_defval)
//#define SIMPLE_METHODDEF
#ifdef DEBUG_METHODS_ENABLED
struct MethodDefinition {
StringName name;
Vector<StringName> args;
MethodDefinition() {}
MethodDefinition(const char *p_name) :
name(p_name) {}
MethodDefinition(const StringName &p_name) :
name(p_name) {}
};
MethodDefinition D_METHOD(const char *p_name);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12, const char *p_arg13);
#else
//#define NO_VARIADIC_MACROS
#ifdef NO_VARIADIC_MACROS
static _FORCE_INLINE_ const char *D_METHOD(const char *m_name, ...) {
return m_name;
}
#else
// When DEBUG_METHODS_ENABLED is set this will let the engine know
// the argument names for easier debugging.
#define D_METHOD(m_c, ...) m_c
#endif
#endif
class ClassDB {
public:
enum APIType {
API_CORE,
API_EDITOR,
API_NONE
};
public:
struct PropertySetGet {
int index;
StringName setter;
StringName getter;
MethodBind *_setptr;
MethodBind *_getptr;
Variant::Type type;
};
struct ClassInfo {
APIType api;
ClassInfo *inherits_ptr;
void *class_ptr;
HashMap<StringName, MethodBind *> method_map;
HashMap<StringName, int> constant_map;
HashMap<StringName, List<StringName> > enum_map;
HashMap<StringName, MethodInfo> signal_map;
List<PropertyInfo> property_list;
#ifdef DEBUG_METHODS_ENABLED
List<StringName> constant_order;
List<StringName> method_order;
Set<StringName> methods_in_properties;
List<MethodInfo> virtual_methods;
StringName category;
#endif
HashMap<StringName, PropertySetGet> property_setget;
StringName inherits;
StringName name;
bool disabled;
bool exposed;
Object *(*creation_func)();
ClassInfo();
~ClassInfo();
};
template <class T>
static Object *creator() {
return memnew(T);
}
static RWLock lock;
static HashMap<StringName, ClassInfo> classes;
static HashMap<StringName, StringName> resource_base_extensions;
static HashMap<StringName, StringName> compat_classes;
#ifdef DEBUG_METHODS_ENABLED
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount);
#else
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const char *method_name, const Variant **p_defs, int p_defcount);
#endif
static APIType current_api;
static void _add_class2(const StringName &p_class, const StringName &p_inherits);
static HashMap<StringName, HashMap<StringName, Variant> > default_values;
static Set<StringName> default_values_cached;
private:
// Non-locking variants of get_parent_class and is_parent_class.
static StringName _get_parent_class(const StringName &p_class);
static bool _is_parent_class(const StringName &p_class, const StringName &p_inherits);
public:
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
template <class T>
static void _add_class() {
_add_class2(T::get_class_static(), T::get_parent_class_static());
}
template <class T>
static void register_class() {
GLOBAL_LOCK_FUNCTION;
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_COND(!t);
t->creation_func = &creator<T>;
t->exposed = true;
t->class_ptr = T::get_class_ptr_static();
T::register_custom_data_to_otdb();
}
template <class T>
static void register_virtual_class() {
GLOBAL_LOCK_FUNCTION;
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_COND(!t);
t->exposed = true;
t->class_ptr = T::get_class_ptr_static();
//nothing
}
template <class T>
static Object *_create_ptr_func() {
return T::create();
}
template <class T>
static void register_custom_instance_class() {
GLOBAL_LOCK_FUNCTION;
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_COND(!t);
t->creation_func = &_create_ptr_func<T>;
t->exposed = true;
t->class_ptr = T::get_class_ptr_static();
T::register_custom_data_to_otdb();
}
static void get_class_list(List<StringName> *p_classes);
static void get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
static void get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
static StringName get_parent_class_nocheck(const StringName &p_class);
static StringName get_parent_class(const StringName &p_class);
static bool class_exists(const StringName &p_class);
static bool is_parent_class(const StringName &p_class, const StringName &p_inherits);
static bool can_instance(const StringName &p_class);
static Object *instance(const StringName &p_class);
static APIType get_api_type(const StringName &p_class);
static uint64_t get_api_hash(APIType p_api);
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method) {
MethodBind *bind = create_method_bind(p_method);
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, NULL, 0); //use static function, much smaller binary usage
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[1] = { &p_def1 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 1);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[2] = { &p_def1, &p_def2 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 2);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[3] = { &p_def1, &p_def2, &p_def3 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 3);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[4] = { &p_def1, &p_def2, &p_def3, &p_def4 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 4);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[5] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 5);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[6] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 6);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[7] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 7);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7, const Variant &p_def8) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[8] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7, &p_def8 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 8);
}
template <class M>
static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>(), bool p_return_nil_is_variant = true) {
GLOBAL_LOCK_FUNCTION;
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
ERR_FAIL_COND_V(!bind, NULL);
bind->set_name(p_name);
bind->set_default_arguments(p_default_args);
String instance_type = bind->get_instance_class();
ClassInfo *type = classes.getptr(instance_type);
if (!type) {
memdelete(bind);
ERR_FAIL_COND_V(!type, NULL);
}
if (type->method_map.has(p_name)) {
memdelete(bind);
// overloading not supported
ERR_FAIL_V_MSG(NULL, "Method already bound: " + instance_type + "::" + p_name + ".");
}
type->method_map[p_name] = bind;
#ifdef DEBUG_METHODS_ENABLED
// FIXME: <reduz> set_return_type is no longer in MethodBind, so I guess it should be moved to vararg method bind
//bind->set_return_type("Variant");
type->method_order.push_back(p_name);
#endif
return bind;
}
static void add_signal(StringName p_class, const MethodInfo &p_signal);
static bool has_signal(StringName p_class, StringName p_signal);
static bool get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal);
static void get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false);
static void add_property_group(StringName p_class, const String &p_name, const String &p_prefix = "");
static void add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
static void set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default);
static void get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = NULL);
static bool set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid = NULL);
static bool get_property(Object *p_object, const StringName &p_property, Variant &r_value);
static bool has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance = false);
static int get_property_index(const StringName &p_class, const StringName &p_property, bool *r_is_valid = NULL);
static Variant::Type get_property_type(const StringName &p_class, const StringName &p_property, bool *r_is_valid = NULL);
static StringName get_property_setter(StringName p_class, const StringName &p_property);
static StringName get_property_getter(StringName p_class, const StringName &p_property);
static bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false);
static void set_method_flags(StringName p_class, StringName p_method, int p_flags);
static void get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
static MethodBind *get_method(StringName p_class, StringName p_name);
static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true);
static void get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false);
static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int p_constant);
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);
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);
static Variant class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid = NULL);
static StringName get_category(const StringName &p_node);
static void set_class_enabled(StringName p_class, bool p_enable);
static bool is_class_enabled(StringName p_class);
static bool is_class_exposed(StringName p_class);
static void add_resource_base_extension(const StringName &p_extension, const StringName &p_class);
static void get_resource_base_extensions(List<String> *p_extensions);
static void get_extensions_for_type(const StringName &p_class, List<String> *p_extensions);
static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback);
static void set_current_api(APIType p_api);
static APIType get_current_api();
static void cleanup_defaults();
static void cleanup();
};
#ifdef DEBUG_METHODS_ENABLED
#define BIND_CONSTANT(m_constant) \
ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
#define BIND_ENUM_CONSTANT(m_constant) \
ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant);
#else
#define BIND_CONSTANT(m_constant) \
ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
#define BIND_ENUM_CONSTANT(m_constant) \
ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
#endif
#ifdef TOOLS_ENABLED
#define BIND_VMETHOD(m_method) \
ClassDB::add_virtual_method(get_class_static(), m_method);
#else
#define BIND_VMETHOD(m_method)
#endif
#endif // CLASS_DB_H

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,135 +26,81 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "color.h"
#include "math_funcs.h"
#include "print_string.h"
#include "core/color_names.inc"
#include "core/map.h"
#include "core/math/math_funcs.h"
#include "core/print_string.h"
uint32_t Color::to_ARGB32() const {
uint32_t Color::to_argb32() const {
uint32_t c = (uint8_t)Math::round(a * 255);
c <<= 8;
c |= (uint8_t)Math::round(r * 255);
c <<= 8;
c |= (uint8_t)Math::round(g * 255);
c <<= 8;
c |= (uint8_t)Math::round(b * 255);
uint32_t c=(uint8_t)(a*255);
c<<=8;
c|=(uint8_t)(r*255);
c<<=8;
c|=(uint8_t)(g*255);
c<<=8;
c|=(uint8_t)(b*255);
return c;
}
uint32_t Color::to_abgr32() const {
uint32_t Color::to_32() const {
uint32_t c = (uint8_t)Math::round(a * 255);
c <<= 8;
c |= (uint8_t)Math::round(b * 255);
c <<= 8;
c |= (uint8_t)Math::round(g * 255);
c <<= 8;
c |= (uint8_t)Math::round(r * 255);
return c;
}
uint32_t Color::to_rgba32() const {
uint32_t c = (uint8_t)Math::round(r * 255);
c <<= 8;
c |= (uint8_t)Math::round(g * 255);
c <<= 8;
c |= (uint8_t)Math::round(b * 255);
c <<= 8;
c |= (uint8_t)Math::round(a * 255);
return c;
}
uint64_t Color::to_abgr64() const {
uint64_t c = (uint16_t)Math::round(a * 65535);
c <<= 16;
c |= (uint16_t)Math::round(b * 65535);
c <<= 16;
c |= (uint16_t)Math::round(g * 65535);
c <<= 16;
c |= (uint16_t)Math::round(r * 65535);
return c;
}
uint64_t Color::to_argb64() const {
uint64_t c = (uint16_t)Math::round(a * 65535);
c <<= 16;
c |= (uint16_t)Math::round(r * 65535);
c <<= 16;
c |= (uint16_t)Math::round(g * 65535);
c <<= 16;
c |= (uint16_t)Math::round(b * 65535);
return c;
}
uint64_t Color::to_rgba64() const {
uint64_t c = (uint16_t)Math::round(r * 65535);
c <<= 16;
c |= (uint16_t)Math::round(g * 65535);
c <<= 16;
c |= (uint16_t)Math::round(b * 65535);
c <<= 16;
c |= (uint16_t)Math::round(a * 65535);
uint32_t c=(uint8_t)(a*255);
c<<=8;
c|=(uint8_t)(r*255);
c<<=8;
c|=(uint8_t)(g*255);
c<<=8;
c|=(uint8_t)(b*255);
return c;
}
float Color::get_h() const {
float min = MIN(r, g);
min = MIN(min, b);
float max = MAX(r, g);
max = MAX(max, b);
float min = MIN( r, g );
min = MIN( min, b );
float max = MAX( r, g );
max = MAX( max, b );
float delta = max - min;
if (delta == 0)
if( delta == 0 )
return 0;
float h;
if (r == max)
h = (g - b) / delta; // between yellow & magenta
else if (g == max)
h = 2 + (b - r) / delta; // between cyan & yellow
if( r == max )
h = ( g - b ) / delta; // between yellow & magenta
else if( g == max )
h = 2 + ( b - r ) / delta; // between cyan & yellow
else
h = 4 + (r - g) / delta; // between magenta & cyan
h /= 6.0;
if (h < 0)
h += 1.0;
h = 4 + ( r - g ) / delta; // between magenta & cyan
h/=6.0;
if (h<0)
h+=1.0;
return h;
}
float Color::get_s() const {
float min = MIN(r, g);
min = MIN(min, b);
float max = MAX(r, g);
max = MAX(max, b);
float min = MIN( r, g );
min = MIN( min, b );
float max = MAX( r, g );
max = MAX( max, b );
float delta = max - min;
return (max != 0) ? (delta / max) : 0;
return (max!=0) ? (delta / max) : 0;
}
float Color::get_v() const {
float max = MAX(r, g);
max = MAX(max, b);
float max = MAX( r, g );
max = MAX( max, b );
return max;
}
@ -163,30 +108,28 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
int i;
float f, p, q, t;
a = p_alpha;
a=p_alpha;
if (p_s == 0) {
if( p_s == 0 ) {
// acp_hromatic (grey)
r = g = b = p_v;
return;
}
p_h *= 6.0;
p_h = Math::fmod(p_h, 6);
i = Math::floor(p_h);
p_h *=6.0;
i = Math::floor( p_h );
f = p_h - i;
p = p_v * (1 - p_s);
q = p_v * (1 - p_s * f);
t = p_v * (1 - p_s * (1 - f));
p = p_v * ( 1 - p_s );
q = p_v * ( 1 - p_s * f );
t = p_v * ( 1 - p_s * ( 1 - f ) );
switch (i) {
case 0: // Red is the dominant color
switch( i ) {
case 0:
r = p_v;
g = t;
b = p;
break;
case 1: // Green is the dominant color
case 1:
r = q;
g = p_v;
b = p;
@ -196,7 +139,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
g = p_v;
b = t;
break;
case 3: // Blue is the dominant color
case 3:
r = p;
g = q;
b = p_v;
@ -206,7 +149,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
g = p;
b = p_v;
break;
default: // (5) Red is the dominant color
default: // cap_se 5:
r = p_v;
g = p;
b = q;
@ -214,379 +157,221 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
}
}
bool Color::is_equal_approx(const Color &p_color) const {
return Math::is_equal_approx(r, p_color.r) && Math::is_equal_approx(g, p_color.g) && Math::is_equal_approx(b, p_color.b) && Math::is_equal_approx(a, p_color.a);
}
void Color::invert() {
r = 1.0 - r;
g = 1.0 - g;
b = 1.0 - b;
r=1.0-r;
g=1.0-g;
g=1.0-b;
}
void Color::contrast() {
r = Math::fmod(r + 0.5, 1.0);
g = Math::fmod(g + 0.5, 1.0);
b = Math::fmod(b + 0.5, 1.0);
r=Math::fmod(r+0.5,1.0);
g=Math::fmod(g+0.5,1.0);
b=Math::fmod(b+0.5,1.0);
}
Color Color::hex(uint32_t p_hex) {
float a = (p_hex & 0xFF) / 255.0;
p_hex >>= 8;
float b = (p_hex & 0xFF) / 255.0;
p_hex >>= 8;
float g = (p_hex & 0xFF) / 255.0;
p_hex >>= 8;
float r = (p_hex & 0xFF) / 255.0;
float a = (p_hex&0xFF)/255.0;
p_hex>>=8;
float b = (p_hex&0xFF)/255.0;
p_hex>>=8;
float g = (p_hex&0xFF)/255.0;
p_hex>>=8;
float r = (p_hex&0xFF)/255.0;
return Color(r, g, b, a);
return Color(r,g,b,a);
}
Color Color::hex64(uint64_t p_hex) {
static float _parse_col(const String& p_str, int p_ofs) {
float a = (p_hex & 0xFFFF) / 65535.0;
p_hex >>= 16;
float b = (p_hex & 0xFFFF) / 65535.0;
p_hex >>= 16;
float g = (p_hex & 0xFFFF) / 65535.0;
p_hex >>= 16;
float r = (p_hex & 0xFFFF) / 65535.0;
int ig=0;
return Color(r, g, b, a);
}
for(int i=0;i<2;i++) {
Color Color::from_rgbe9995(uint32_t p_rgbe) {
int c=p_str[i+p_ofs];
int v=0;
float r = p_rgbe & 0x1ff;
float g = (p_rgbe >> 9) & 0x1ff;
float b = (p_rgbe >> 18) & 0x1ff;
float e = (p_rgbe >> 27);
float m = Math::pow(2, e - 15.0 - 9.0);
float rd = r * m;
float gd = g * m;
float bd = b * m;
return Color(rd, gd, bd, 1.0f);
}
static float _parse_col(const String &p_str, int p_ofs) {
int ig = 0;
for (int i = 0; i < 2; i++) {
int c = p_str[i + p_ofs];
int v = 0;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
v = c - 'a';
v += 10;
} else if (c >= 'A' && c <= 'F') {
v = c - 'A';
v += 10;
if (c>='0' && c<='9') {
v=c-'0';
} else if (c>='a' && c<='f') {
v=c-'a';
v+=10;
} else if (c>='A' && c<='F') {
v=c-'A';
v+=10;
} else {
return -1;
}
if (i == 0)
ig += v * 16;
if (i==0)
ig+=v*16;
else
ig += v;
ig+=v;
}
return ig;
}
Color Color::inverted() const {
Color c = *this;
Color c=*this;
c.invert();
return c;
}
Color Color::contrasted() const {
Color c = *this;
Color c=*this;
c.contrast();
return c;
}
Color Color::html(const String &p_color) {
Color Color::html(const String& p_color) {
String color = p_color;
if (color.length() == 0)
if (color.length()==0)
return Color();
if (color[0] == '#')
color = color.substr(1, color.length() - 1);
if (color.length() == 3 || color.length() == 4) {
String exp_color;
for (int i = 0; i < color.length(); i++) {
exp_color += color[i];
exp_color += color[i];
}
color = exp_color;
}
if (color[0]=='#')
color=color.substr(1,color.length()-1);
bool alpha = false;
bool alpha=false;
if (color.length() == 8) {
alpha = true;
} else if (color.length() == 6) {
alpha = false;
if (color.length()==8) {
alpha=true;
} else if (color.length()==6) {
alpha=false;
} else {
ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_color + ".");
ERR_EXPLAIN("Invalid Color Code: "+p_color);
ERR_FAIL_V(Color());
}
int a = 255;
int a=255;
if (alpha) {
a = _parse_col(color, 0);
ERR_FAIL_COND_V_MSG(a < 0, Color(), "Invalid color code: " + p_color + ".");
a=_parse_col(color,0);
if (a<0) {
ERR_EXPLAIN("Invalid Color Code: "+p_color);
ERR_FAIL_V(Color());
}
}
int from = alpha ? 2 : 0;
int from=alpha?2:0;
int r = _parse_col(color, from + 0);
ERR_FAIL_COND_V_MSG(r < 0, Color(), "Invalid color code: " + p_color + ".");
int g = _parse_col(color, from + 2);
ERR_FAIL_COND_V_MSG(g < 0, Color(), "Invalid color code: " + p_color + ".");
int b = _parse_col(color, from + 4);
ERR_FAIL_COND_V_MSG(b < 0, Color(), "Invalid color code: " + p_color + ".");
int r=_parse_col(color,from+0);
if (r<0) {
ERR_EXPLAIN("Invalid Color Code: "+p_color);
ERR_FAIL_V(Color());
}
int g=_parse_col(color,from+2);
if (g<0) {
ERR_EXPLAIN("Invalid Color Code: "+p_color);
ERR_FAIL_V(Color());
}
int b=_parse_col(color,from+4);
if (b<0) {
ERR_EXPLAIN("Invalid Color Code: "+p_color);
ERR_FAIL_V(Color());
}
return Color(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
return Color(r/255.0,g/255.0,b/255.0,a/255.0);
}
bool Color::html_is_valid(const String &p_color) {
bool Color::html_is_valid(const String& p_color) {
String color = p_color;
if (color.length() == 0)
if (color.length()==0)
return false;
if (color[0] == '#')
color = color.substr(1, color.length() - 1);
if (color[0]=='#')
color=color.substr(1,color.length()-1);
bool alpha = false;
bool alpha=false;
if (color.length() == 8) {
alpha = true;
} else if (color.length() == 6) {
alpha = false;
if (color.length()==8) {
alpha=true;
} else if (color.length()==6) {
alpha=false;
} else {
return false;
}
int a=255;
if (alpha) {
int a = _parse_col(color, 0);
if (a < 0) {
a=_parse_col(color,0);
if (a<0) {
return false;
}
}
int from = alpha ? 2 : 0;
int from=alpha?2:0;
int r = _parse_col(color, from + 0);
if (r < 0) {
int r=_parse_col(color,from+0);
if (r<0) {
return false;
}
int g = _parse_col(color, from + 2);
if (g < 0) {
int g=_parse_col(color,from+2);
if (g<0) {
return false;
}
int b = _parse_col(color, from + 4);
if (b < 0) {
int b=_parse_col(color,from+4);
if (b<0) {
return false;
}
return true;
}
Color Color::named(const String &p_name) {
if (_named_colors.empty()) _populate_named_colors(); // from color_names.inc
String name = p_name;
// Normalize name
name = name.replace(" ", "");
name = name.replace("-", "");
name = name.replace("_", "");
name = name.replace("'", "");
name = name.replace(".", "");
name = name.to_lower();
const Map<String, Color>::Element *color = _named_colors.find(name);
ERR_FAIL_NULL_V_MSG(color, Color(), "Invalid color name: " + p_name + ".");
return color->value();
}
String _to_hex(float p_val) {
int v = Math::round(p_val * 255);
v = CLAMP(v, 0, 255);
int v = p_val * 255;
v = CLAMP(v,0,255);
String ret;
for (int i = 0; i < 2; i++) {
for(int i=0;i<2;i++) {
CharType c[2] = { 0, 0 };
int lv = v & 0xF;
if (lv < 10)
c[0] = '0' + lv;
CharType c[2]={0,0};
int lv = v&0xF;
if (lv<10)
c[0]='0'+lv;
else
c[0] = 'a' + lv - 10;
c[0]='a'+lv-10;
v >>= 4;
String cs = (const CharType *)c;
v>>=4;
String cs=(const CharType*)c;
ret = cs + ret;
}
return ret;
}
String Color::to_html(bool p_alpha) const {
String txt;
txt += _to_hex(r);
txt += _to_hex(g);
txt += _to_hex(b);
txt+=_to_hex(r);
txt+=_to_hex(g);
txt+=_to_hex(b);
if (p_alpha)
txt = _to_hex(a) + txt;
txt=_to_hex(a)+txt;
return txt;
}
Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
Color c;
c.set_hsv(p_h, p_s, p_v, p_a);
return c;
}
// FIXME: Remove once Godot 3.1 has been released
float Color::gray() const {
WARN_DEPRECATED_MSG("'Color.gray()' is deprecated and will be removed in a future version. Use 'Color.v' for a better grayscale approximation.");
return (r + g + b) / 3.0;
return (r+g+b)/3.0;
}
Color::operator String() const {
return rtos(r) + ", " + rtos(g) + ", " + rtos(b) + ", " + rtos(a);
return rtos(r)+", "+rtos(g)+", "+rtos(b)+", "+rtos(a);
}
Color Color::operator+(const Color &p_color) const {
return Color(
r + p_color.r,
g + p_color.g,
b + p_color.b,
a + p_color.a);
}
void Color::operator+=(const Color &p_color) {
r = r + p_color.r;
g = g + p_color.g;
b = b + p_color.b;
a = a + p_color.a;
}
Color Color::operator-(const Color &p_color) const {
return Color(
r - p_color.r,
g - p_color.g,
b - p_color.b,
a - p_color.a);
}
void Color::operator-=(const Color &p_color) {
r = r - p_color.r;
g = g - p_color.g;
b = b - p_color.b;
a = a - p_color.a;
}
Color Color::operator*(const Color &p_color) const {
return Color(
r * p_color.r,
g * p_color.g,
b * p_color.b,
a * p_color.a);
}
Color Color::operator*(const real_t &rvalue) const {
return Color(
r * rvalue,
g * rvalue,
b * rvalue,
a * rvalue);
}
void Color::operator*=(const Color &p_color) {
r = r * p_color.r;
g = g * p_color.g;
b = b * p_color.b;
a = a * p_color.a;
}
void Color::operator*=(const real_t &rvalue) {
r = r * rvalue;
g = g * rvalue;
b = b * rvalue;
a = a * rvalue;
}
Color Color::operator/(const Color &p_color) const {
return Color(
r / p_color.r,
g / p_color.g,
b / p_color.b,
a / p_color.a);
}
Color Color::operator/(const real_t &rvalue) const {
return Color(
r / rvalue,
g / rvalue,
b / rvalue,
a / rvalue);
}
void Color::operator/=(const Color &p_color) {
r = r / p_color.r;
g = g / p_color.g;
b = b / p_color.b;
a = a / p_color.a;
}
void Color::operator/=(const real_t &rvalue) {
if (rvalue == 0) {
r = 1.0;
g = 1.0;
b = 1.0;
a = 1.0;
} else {
r = r / rvalue;
g = g / rvalue;
b = b / rvalue;
a = a / rvalue;
}
};
Color Color::operator-() const {
return Color(
1.0 - r,
1.0 - g,
1.0 - b,
1.0 - a);
}

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,147 +26,74 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef COLOR_H
#define COLOR_H
#include "core/math/math_funcs.h"
#include "core/ustring.h"
#include "ustring.h"
#include "math_funcs.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
struct Color {
union {
struct {
float r;
float g;
float b;
float a;
};
};
float components[4];
};
bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); }
bool operator!=(const Color &p_color) const { return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); }
bool operator==(const Color &p_color) const { return (r==p_color.r && g==p_color.g && b==p_color.b && a==p_color.a ); }
bool operator!=(const Color &p_color) const { return (r!=p_color.r || g!=p_color.g || b!=p_color.b || a!=p_color.a ); }
uint32_t to_rgba32() const;
uint32_t to_argb32() const;
uint32_t to_abgr32() const;
uint64_t to_rgba64() const;
uint64_t to_argb64() const;
uint64_t to_abgr64() const;
uint32_t to_32() const;
uint32_t to_ARGB32() const;
float gray() const;
float get_h() const;
float get_s() const;
float get_v() const;
void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0);
void set_hsv(float p_h, float p_s, float p_v, float p_alpha=1.0);
_FORCE_INLINE_ float &operator[](int idx) {
_FORCE_INLINE_ float& operator[](int idx) {
return components[idx];
}
_FORCE_INLINE_ const float &operator[](int idx) const {
_FORCE_INLINE_ const float& operator[](int idx) const {
return components[idx];
}
Color operator+(const Color &p_color) const;
void operator+=(const Color &p_color);
Color operator-() const;
Color operator-(const Color &p_color) const;
void operator-=(const Color &p_color);
Color operator*(const Color &p_color) const;
Color operator*(const real_t &rvalue) const;
void operator*=(const Color &p_color);
void operator*=(const real_t &rvalue);
Color operator/(const Color &p_color) const;
Color operator/(const real_t &rvalue) const;
void operator/=(const Color &p_color);
void operator/=(const real_t &rvalue);
bool is_equal_approx(const Color &p_color) const;
void invert();
void contrast();
Color inverted() const;
Color contrasted() const;
_FORCE_INLINE_ Color linear_interpolate(const Color &p_to, float p_weight) const {
Color res = *this;
res.r += (p_weight * (p_to.r - r));
res.g += (p_weight * (p_to.g - g));
res.b += (p_weight * (p_to.b - b));
res.a += (p_weight * (p_to.a - a));
return res;
_FORCE_INLINE_ Color linear_interpolate(const Color& p_b, float p_t) const {
Color res=*this;
res.r+= (p_t * (p_b.r-r));
res.g+= (p_t * (p_b.g-g));
res.b+= (p_t * (p_b.b-b));
res.a+= (p_t * (p_b.a-a));
return res;
}
_FORCE_INLINE_ Color darkened(float p_amount) const {
_FORCE_INLINE_ Color blend(const Color& p_over) const {
Color res = *this;
res.r = res.r * (1.0f - p_amount);
res.g = res.g * (1.0f - p_amount);
res.b = res.b * (1.0f - p_amount);
return res;
}
_FORCE_INLINE_ Color lightened(float p_amount) const {
Color res = *this;
res.r = res.r + (1.0f - res.r) * p_amount;
res.g = res.g + (1.0f - res.g) * p_amount;
res.b = res.b + (1.0f - res.b) * p_amount;
return res;
}
_FORCE_INLINE_ uint32_t to_rgbe9995() const {
const float pow2to9 = 512.0f;
const float B = 15.0f;
//const float Emax = 31.0f;
const float N = 9.0f;
float sharedexp = 65408.000f; //(( pow2to9 - 1.0f)/ pow2to9)*powf( 2.0f, 31.0f - 15.0f);
float cRed = MAX(0.0f, MIN(sharedexp, r));
float cGreen = MAX(0.0f, MIN(sharedexp, g));
float cBlue = MAX(0.0f, MIN(sharedexp, b));
float cMax = MAX(cRed, MAX(cGreen, cBlue));
// expp = MAX(-B - 1, log2(maxc)) + 1 + B
float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B;
float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f);
float exps = expp + 1.0f;
if (0.0 <= sMax && sMax < pow2to9) {
exps = expp;
}
float sRed = Math::floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
float sGreen = Math::floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
float sBlue = Math::floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
return (uint32_t(Math::fast_ftoi(sRed)) & 0x1FF) | ((uint32_t(Math::fast_ftoi(sGreen)) & 0x1FF) << 9) | ((uint32_t(Math::fast_ftoi(sBlue)) & 0x1FF) << 18) | ((uint32_t(Math::fast_ftoi(exps)) & 0x1F) << 27);
}
_FORCE_INLINE_ Color blend(const Color &p_over) const {
Color res;
float sa = 1.0 - p_over.a;
res.a = a * sa + p_over.a;
if (res.a == 0) {
return Color(0, 0, 0, 0);
res.a = a*sa+p_over.a;
if (res.a==0) {
return Color(0,0,0,0);
} else {
res.r = (r * a * sa + p_over.r * p_over.a) / res.a;
res.g = (g * a * sa + p_over.g * p_over.a) / res.a;
res.b = (b * a * sa + p_over.b * p_over.a) / res.a;
res.r = (r*a*sa + p_over.r * p_over.a)/res.a;
res.g = (g*a*sa + p_over.g * p_over.a)/res.a;
res.b = (b*a*sa + p_over.b * p_over.a)/res.a;
}
return res;
}
@ -175,64 +101,47 @@ struct Color {
_FORCE_INLINE_ Color to_linear() const {
return Color(
r < 0.04045 ? r * (1.0 / 12.92) : Math::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4),
g < 0.04045 ? g * (1.0 / 12.92) : Math::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4),
b < 0.04045 ? b * (1.0 / 12.92) : Math::pow((b + 0.055) * (1.0 / (1 + 0.055)), 2.4),
a);
}
_FORCE_INLINE_ Color to_srgb() const {
return Color(
r < 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math::pow(r, 1.0f / 2.4f) - 0.055,
g < 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math::pow(g, 1.0f / 2.4f) - 0.055,
b < 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math::pow(b, 1.0f / 2.4f) - 0.055, a);
r<0.04045 ? r * (1.0 / 12.92) : Math::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4),
g<0.04045 ? g * (1.0 / 12.92) : Math::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4),
b<0.04045 ? b * (1.0 / 12.92) : Math::pow((b + 0.055) * (1.0 / (1 + 0.055)), 2.4),
a
);
}
static Color hex(uint32_t p_hex);
static Color hex64(uint64_t p_hex);
static Color html(const String &p_color);
static bool html_is_valid(const String &p_color);
static Color named(const String &p_name);
String to_html(bool p_alpha = true) const;
Color from_hsv(float p_h, float p_s, float p_v, float p_a) const;
static Color from_rgbe9995(uint32_t p_rgbe);
static Color html(const String& p_color);
static bool html_is_valid(const String& p_color);
String to_html(bool p_alpha=true) const;
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
_FORCE_INLINE_ bool operator<(const Color& p_color) const; //used in set keys
operator String() const;
/**
* No construct parameters, r=0, g=0, b=0. a=255
*/
_FORCE_INLINE_ Color() {
r = 0;
g = 0;
b = 0;
a = 1.0;
r=0; g=0; b=0; a=1.0;
}
/**
* RGB / RGBA construct parameters. Alpha is optional, but defaults to 1.0
*/
_FORCE_INLINE_ Color(float p_r, float p_g, float p_b, float p_a = 1.0) {
r = p_r;
g = p_g;
b = p_b;
a = p_a;
}
_FORCE_INLINE_ Color(float p_r,float p_g,float p_b,float p_a=1.0) { r=p_r; g=p_g; b=p_b; a=p_a; }
};
bool Color::operator<(const Color &p_color) const {
bool Color::operator<(const Color& p_color) const {
if (r == p_color.r) {
if (g == p_color.g) {
if (b == p_color.b) {
return (a < p_color.a);
if (r==p_color.r) {
if (g==p_color.g) {
if(b==p_color.b) {
return (a<p_color.a);
} else
return (b < p_color.b);
return (b<p_color.b);
} else
return g < p_color.g;
return g<p_color.g;
} else
return r < p_color.r;
return r<p_color.r;
}
#endif

View File

@ -1,153 +0,0 @@
// Names from https://en.wikipedia.org/wiki/X11_color_names
#include "core/map.h"
static Map<String, Color> _named_colors;
static void _populate_named_colors() {
if (!_named_colors.empty()) return;
_named_colors.insert("aliceblue", Color(0.94, 0.97, 1.00));
_named_colors.insert("antiquewhite", Color(0.98, 0.92, 0.84));
_named_colors.insert("aqua", Color(0.00, 1.00, 1.00));
_named_colors.insert("aquamarine", Color(0.50, 1.00, 0.83));
_named_colors.insert("azure", Color(0.94, 1.00, 1.00));
_named_colors.insert("beige", Color(0.96, 0.96, 0.86));
_named_colors.insert("bisque", Color(1.00, 0.89, 0.77));
_named_colors.insert("black", Color(0.00, 0.00, 0.00));
_named_colors.insert("blanchedalmond", Color(1.00, 0.92, 0.80));
_named_colors.insert("blue", Color(0.00, 0.00, 1.00));
_named_colors.insert("blueviolet", Color(0.54, 0.17, 0.89));
_named_colors.insert("brown", Color(0.65, 0.16, 0.16));
_named_colors.insert("burlywood", Color(0.87, 0.72, 0.53));
_named_colors.insert("cadetblue", Color(0.37, 0.62, 0.63));
_named_colors.insert("chartreuse", Color(0.50, 1.00, 0.00));
_named_colors.insert("chocolate", Color(0.82, 0.41, 0.12));
_named_colors.insert("coral", Color(1.00, 0.50, 0.31));
_named_colors.insert("cornflower", Color(0.39, 0.58, 0.93));
_named_colors.insert("cornsilk", Color(1.00, 0.97, 0.86));
_named_colors.insert("crimson", Color(0.86, 0.08, 0.24));
_named_colors.insert("cyan", Color(0.00, 1.00, 1.00));
_named_colors.insert("darkblue", Color(0.00, 0.00, 0.55));
_named_colors.insert("darkcyan", Color(0.00, 0.55, 0.55));
_named_colors.insert("darkgoldenrod", Color(0.72, 0.53, 0.04));
_named_colors.insert("darkgray", Color(0.66, 0.66, 0.66));
_named_colors.insert("darkgreen", Color(0.00, 0.39, 0.00));
_named_colors.insert("darkkhaki", Color(0.74, 0.72, 0.42));
_named_colors.insert("darkmagenta", Color(0.55, 0.00, 0.55));
_named_colors.insert("darkolivegreen", Color(0.33, 0.42, 0.18));
_named_colors.insert("darkorange", Color(1.00, 0.55, 0.00));
_named_colors.insert("darkorchid", Color(0.60, 0.20, 0.80));
_named_colors.insert("darkred", Color(0.55, 0.00, 0.00));
_named_colors.insert("darksalmon", Color(0.91, 0.59, 0.48));
_named_colors.insert("darkseagreen", Color(0.56, 0.74, 0.56));
_named_colors.insert("darkslateblue", Color(0.28, 0.24, 0.55));
_named_colors.insert("darkslategray", Color(0.18, 0.31, 0.31));
_named_colors.insert("darkturquoise", Color(0.00, 0.81, 0.82));
_named_colors.insert("darkviolet", Color(0.58, 0.00, 0.83));
_named_colors.insert("deeppink", Color(1.00, 0.08, 0.58));
_named_colors.insert("deepskyblue", Color(0.00, 0.75, 1.00));
_named_colors.insert("dimgray", Color(0.41, 0.41, 0.41));
_named_colors.insert("dodgerblue", Color(0.12, 0.56, 1.00));
_named_colors.insert("firebrick", Color(0.70, 0.13, 0.13));
_named_colors.insert("floralwhite", Color(1.00, 0.98, 0.94));
_named_colors.insert("forestgreen", Color(0.13, 0.55, 0.13));
_named_colors.insert("fuchsia", Color(1.00, 0.00, 1.00));
_named_colors.insert("gainsboro", Color(0.86, 0.86, 0.86));
_named_colors.insert("ghostwhite", Color(0.97, 0.97, 1.00));
_named_colors.insert("gold", Color(1.00, 0.84, 0.00));
_named_colors.insert("goldenrod", Color(0.85, 0.65, 0.13));
_named_colors.insert("gray", Color(0.75, 0.75, 0.75));
_named_colors.insert("webgray", Color(0.50, 0.50, 0.50));
_named_colors.insert("green", Color(0.00, 1.00, 0.00));
_named_colors.insert("webgreen", Color(0.00, 0.50, 0.00));
_named_colors.insert("greenyellow", Color(0.68, 1.00, 0.18));
_named_colors.insert("honeydew", Color(0.94, 1.00, 0.94));
_named_colors.insert("hotpink", Color(1.00, 0.41, 0.71));
_named_colors.insert("indianred", Color(0.80, 0.36, 0.36));
_named_colors.insert("indigo", Color(0.29, 0.00, 0.51));
_named_colors.insert("ivory", Color(1.00, 1.00, 0.94));
_named_colors.insert("khaki", Color(0.94, 0.90, 0.55));
_named_colors.insert("lavender", Color(0.90, 0.90, 0.98));
_named_colors.insert("lavenderblush", Color(1.00, 0.94, 0.96));
_named_colors.insert("lawngreen", Color(0.49, 0.99, 0.00));
_named_colors.insert("lemonchiffon", Color(1.00, 0.98, 0.80));
_named_colors.insert("lightblue", Color(0.68, 0.85, 0.90));
_named_colors.insert("lightcoral", Color(0.94, 0.50, 0.50));
_named_colors.insert("lightcyan", Color(0.88, 1.00, 1.00));
_named_colors.insert("lightgoldenrod", Color(0.98, 0.98, 0.82));
_named_colors.insert("lightgray", Color(0.83, 0.83, 0.83));
_named_colors.insert("lightgreen", Color(0.56, 0.93, 0.56));
_named_colors.insert("lightpink", Color(1.00, 0.71, 0.76));
_named_colors.insert("lightsalmon", Color(1.00, 0.63, 0.48));
_named_colors.insert("lightseagreen", Color(0.13, 0.70, 0.67));
_named_colors.insert("lightskyblue", Color(0.53, 0.81, 0.98));
_named_colors.insert("lightslategray", Color(0.47, 0.53, 0.60));
_named_colors.insert("lightsteelblue", Color(0.69, 0.77, 0.87));
_named_colors.insert("lightyellow", Color(1.00, 1.00, 0.88));
_named_colors.insert("lime", Color(0.00, 1.00, 0.00));
_named_colors.insert("limegreen", Color(0.20, 0.80, 0.20));
_named_colors.insert("linen", Color(0.98, 0.94, 0.90));
_named_colors.insert("magenta", Color(1.00, 0.00, 1.00));
_named_colors.insert("maroon", Color(0.69, 0.19, 0.38));
_named_colors.insert("webmaroon", Color(0.50, 0.00, 0.00));
_named_colors.insert("mediumaquamarine", Color(0.40, 0.80, 0.67));
_named_colors.insert("mediumblue", Color(0.00, 0.00, 0.80));
_named_colors.insert("mediumorchid", Color(0.73, 0.33, 0.83));
_named_colors.insert("mediumpurple", Color(0.58, 0.44, 0.86));
_named_colors.insert("mediumseagreen", Color(0.24, 0.70, 0.44));
_named_colors.insert("mediumslateblue", Color(0.48, 0.41, 0.93));
_named_colors.insert("mediumspringgreen", Color(0.00, 0.98, 0.60));
_named_colors.insert("mediumturquoise", Color(0.28, 0.82, 0.80));
_named_colors.insert("mediumvioletred", Color(0.78, 0.08, 0.52));
_named_colors.insert("midnightblue", Color(0.10, 0.10, 0.44));
_named_colors.insert("mintcream", Color(0.96, 1.00, 0.98));
_named_colors.insert("mistyrose", Color(1.00, 0.89, 0.88));
_named_colors.insert("moccasin", Color(1.00, 0.89, 0.71));
_named_colors.insert("navajowhite", Color(1.00, 0.87, 0.68));
_named_colors.insert("navyblue", Color(0.00, 0.00, 0.50));
_named_colors.insert("oldlace", Color(0.99, 0.96, 0.90));
_named_colors.insert("olive", Color(0.50, 0.50, 0.00));
_named_colors.insert("olivedrab", Color(0.42, 0.56, 0.14));
_named_colors.insert("orange", Color(1.00, 0.65, 0.00));
_named_colors.insert("orangered", Color(1.00, 0.27, 0.00));
_named_colors.insert("orchid", Color(0.85, 0.44, 0.84));
_named_colors.insert("palegoldenrod", Color(0.93, 0.91, 0.67));
_named_colors.insert("palegreen", Color(0.60, 0.98, 0.60));
_named_colors.insert("paleturquoise", Color(0.69, 0.93, 0.93));
_named_colors.insert("palevioletred", Color(0.86, 0.44, 0.58));
_named_colors.insert("papayawhip", Color(1.00, 0.94, 0.84));
_named_colors.insert("peachpuff", Color(1.00, 0.85, 0.73));
_named_colors.insert("peru", Color(0.80, 0.52, 0.25));
_named_colors.insert("pink", Color(1.00, 0.75, 0.80));
_named_colors.insert("plum", Color(0.87, 0.63, 0.87));
_named_colors.insert("powderblue", Color(0.69, 0.88, 0.90));
_named_colors.insert("purple", Color(0.63, 0.13, 0.94));
_named_colors.insert("webpurple", Color(0.50, 0.00, 0.50));
_named_colors.insert("rebeccapurple", Color(0.40, 0.20, 0.60));
_named_colors.insert("red", Color(1.00, 0.00, 0.00));
_named_colors.insert("rosybrown", Color(0.74, 0.56, 0.56));
_named_colors.insert("royalblue", Color(0.25, 0.41, 0.88));
_named_colors.insert("saddlebrown", Color(0.55, 0.27, 0.07));
_named_colors.insert("salmon", Color(0.98, 0.50, 0.45));
_named_colors.insert("sandybrown", Color(0.96, 0.64, 0.38));
_named_colors.insert("seagreen", Color(0.18, 0.55, 0.34));
_named_colors.insert("seashell", Color(1.00, 0.96, 0.93));
_named_colors.insert("sienna", Color(0.63, 0.32, 0.18));
_named_colors.insert("silver", Color(0.75, 0.75, 0.75));
_named_colors.insert("skyblue", Color(0.53, 0.81, 0.92));
_named_colors.insert("slateblue", Color(0.42, 0.35, 0.80));
_named_colors.insert("slategray", Color(0.44, 0.50, 0.56));
_named_colors.insert("snow", Color(1.00, 0.98, 0.98));
_named_colors.insert("springgreen", Color(0.00, 1.00, 0.50));
_named_colors.insert("steelblue", Color(0.27, 0.51, 0.71));
_named_colors.insert("tan", Color(0.82, 0.71, 0.55));
_named_colors.insert("teal", Color(0.00, 0.50, 0.50));
_named_colors.insert("thistle", Color(0.85, 0.75, 0.85));
_named_colors.insert("tomato", Color(1.00, 0.39, 0.28));
_named_colors.insert("turquoise", Color(0.25, 0.88, 0.82));
_named_colors.insert("transparent", Color(1.00, 1.00, 1.00, 0.00));
_named_colors.insert("violet", Color(0.93, 0.51, 0.93));
_named_colors.insert("wheat", Color(0.96, 0.87, 0.70));
_named_colors.insert("white", Color(1.00, 1.00, 1.00));
_named_colors.insert("whitesmoke", Color(0.96, 0.96, 0.96));
_named_colors.insert("yellow", Color(1.00, 1.00, 0.00));
_named_colors.insert("yellowgreen", Color(0.60, 0.80, 0.20));
}

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,20 +26,19 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "command_queue_mt.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "os/os.h"
void CommandQueueMT::lock() {
mutex.lock();
if (mutex)
mutex->lock();
}
void CommandQueueMT::unlock() {
mutex.unlock();
if (mutex)
mutex->unlock();
}
void CommandQueueMT::wait_for_flush() {
@ -49,24 +47,22 @@ void CommandQueueMT::wait_for_flush() {
OS::get_singleton()->delay_usec(1000);
}
CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() {
CommandQueueMT::SyncSemaphore* CommandQueueMT::_alloc_sync_sem() {
int idx = -1;
int idx=-1;
while (true) {
while(true) {
lock();
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
for(int i=0;i<SYNC_SEMAPHORES;i++) {
if (!sync_sems[i].in_use) {
sync_sems[i].in_use = true;
idx = i;
sync_sems[i].in_use=true;
idx=i;
break;
}
}
unlock();
if (idx == -1) {
if (idx==-1) {
wait_for_flush();
} else {
break;
@ -76,55 +72,36 @@ CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() {
return &sync_sems[idx];
}
bool CommandQueueMT::dealloc_one() {
tryagain:
if (dealloc_ptr == (write_ptr_and_epoch >> 1)) {
// The queue is empty
return false;
CommandQueueMT::CommandQueueMT(bool p_sync){
read_ptr=0;
write_ptr=0;
mutex = Mutex::create();
for(int i=0;i<SYNC_SEMAPHORES;i++) {
sync_sems[i].sem=Semaphore::create();
sync_sems[i].in_use=false;
}
uint32_t size = *(uint32_t *)&command_mem[dealloc_ptr];
if (size == 0) {
// End of command buffer wrap down
dealloc_ptr = 0;
goto tryagain;
}
if (size & 1) {
// Still used, nothing can be deallocated
return false;
}
dealloc_ptr += (size >> 1) + 8;
return true;
if (p_sync)
sync = Semaphore::create();
else
sync=NULL;
}
CommandQueueMT::CommandQueueMT(bool p_sync) {
read_ptr_and_epoch = 0;
write_ptr_and_epoch = 0;
dealloc_ptr = 0;
command_mem_size = GLOBAL_DEF_RST("memory/limits/command_queue/multithreading_queue_size_kb", DEFAULT_COMMAND_MEM_SIZE_KB);
ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/command_queue/multithreading_queue_size_kb", PropertyInfo(Variant::INT, "memory/limits/command_queue/multithreading_queue_size_kb", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"));
command_mem_size *= 1024;
command_mem = (uint8_t *)memalloc(command_mem_size);
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
sync_sems[i].in_use = false;
}
if (p_sync) {
sync = memnew(Semaphore);
} else {
sync = NULL;
}
}
CommandQueueMT::~CommandQueueMT() {
if (sync)
memdelete(sync);
memfree(command_mem);
memdelete(mutex);
for(int i=0;i<SYNC_SEMAPHORES;i++) {
memdelete(sync_sems[i].sem);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,15 +26,222 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "compressed_translation.h"
#include "pair.h"
#include <string.h>
#include "core/pair.h"
/////////// SMAZ /////////////
extern "C" {
#include "thirdparty/misc/smaz.h"
/*
Copyright (c) 2006-2009, Salvatore Sanfilippo
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of Smaz nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Our compression codebook, used for compression */
static const char *Smaz_cb[241] = {
"\002s,\266", "\003had\232\002leW", "\003on \216", "", "\001yS",
"\002ma\255\002li\227", "\003or \260", "", "\002ll\230\003s t\277",
"\004fromg\002mel", "", "\003its\332", "\001z\333", "\003ingF", "\001>\336",
"\001 \000\003 (\002nc\344", "\002nd=\003 on\312",
"\002ne\213\003hat\276\003re q", "", "\002ngT\003herz\004have\306\003s o\225",
"", "\003ionk\003s a\254\002ly\352", "\003hisL\003 inN\003 be\252", "",
"\003 fo\325\003 of \003 ha\311", "", "\002of\005",
"\003 co\241\002no\267\003 ma\370", "", "", "\003 cl\356\003enta\003 an7",
"\002ns\300\001\"e", "\003n t\217\002ntP\003s, \205",
"\002pe\320\003 we\351\002om\223", "\002on\037", "", "\002y G", "\003 wa\271",
"\003 re\321\002or*", "", "\002=\"\251\002ot\337", "\003forD\002ou[",
"\003 toR", "\003 th\r", "\003 it\366",
"\003but\261\002ra\202\003 wi\363\002</\361", "\003 wh\237", "\002 4",
"\003nd ?", "\002re!", "", "\003ng c", "",
"\003ly \307\003ass\323\001a\004\002rir", "", "", "", "\002se_", "\003of \"",
"\003div\364\002ros\003ere\240", "", "\002ta\310\001bZ\002si\324", "",
"\003and\a\002rs\335", "\002rt\362", "\002teE", "\003ati\316", "\002so\263",
"\002th\021", "\002tiJ\001c\034\003allp", "\003ate\345", "\002ss\246",
"\002stM", "", "\002><\346", "\002to\024", "\003arew", "\001d\030",
"\002tr\303", "", "\001\n1\003 a \222", "\003f tv\002veo", "\002un\340", "",
"\003e o\242", "\002a \243\002wa\326\001e\002", "\002ur\226\003e a\274",
"\002us\244\003\n\r\n\247", "\002ut\304\003e c\373", "\002we\221", "", "",
"\002wh\302", "\001f,", "", "", "", "\003d t\206", "", "", "\003th \343",
"\001g;", "", "", "\001\r9\003e s\265", "\003e t\234", "", "\003to Y",
"\003e\r\n\236", "\002d \036\001h\022", "", "\001,Q", "\002 a\031", "\002 b^",
"\002\r\n\025\002 cI", "\002 d\245", "\002 e\253", "\002 fh\001i\b\002e \v",
"", "\002 hU\001-\314", "\002 i8", "", "", "\002 l\315", "\002 m{",
"\002f :\002 n\354", "\002 o\035", "\002 p}\001.n\003\r\n\r\250", "",
"\002 r\275", "\002 s>", "\002 t\016", "", "\002g \235\005which+\003whi\367",
"\002 w5", "\001/\305", "\003as \214", "\003at \207", "", "\003who\331", "",
"\001l\026\002h \212", "", "\002, $", "", "\004withV", "", "", "", "\001m-", "",
"", "\002ac\357", "\002ad\350", "\003TheH", "", "", "\004this\233\001n\t",
"", "\002. y", "", "\002alX\003e, \365", "\003tio\215\002be\\",
"\002an\032\003ver\347", "", "\004that0\003tha\313\001o\006", "\003was2",
"\002arO", "\002as.", "\002at'\003the\001\004they\200\005there\322\005theird",
"\002ce\210", "\004were]", "", "\002ch\231\002l \264\001p<", "", "",
"\003one\256", "", "\003he \023\002dej", "\003ter\270", "\002cou", "",
"\002by\177\002di\201\002eax", "", "\002ec\327", "\002edB", "\002ee\353", "",
"", "\001r\f\002n )", "", "", "", "\002el\262", "", "\003in i\002en3", "",
"\002o `\001s\n", "", "\002er\033", "\003is t\002es6", "", "\002ge\371",
"\004.com\375", "\002fo\334\003our\330", "\003ch \301\001t\003", "\002hab", "",
"\003men\374", "", "\002he\020", "", "", "\001u&", "\002hif", "",
"\003not\204\002ic\203", "\003ed @\002id\355", "", "", "\002ho\273",
"\002r K\001vm", "", "", "", "\003t t\257\002il\360", "\002im\342",
"\003en \317\002in\017", "\002io\220", "\002s \027\001wA", "", "\003er |",
"\003es ~\002is%", "\002it/", "", "\002iv\272", "",
"\002t #\ahttp://C\001x\372", "\002la\211", "\001<\341", "\003, a\224"
};
/* Reverse compression codebook, used for decompression */
static const char *Smaz_rcb[254] = {
" ", "the", "e", "t", "a", "of", "o", "and", "i", "n", "s", "e ", "r", " th",
" t", "in", "he", "th", "h", "he ", "to", "\r\n", "l", "s ", "d", " a", "an",
"er", "c", " o", "d ", "on", " of", "re", "of ", "t ", ", ", "is", "u", "at",
" ", "n ", "or", "which", "f", "m", "as", "it", "that", "\n", "was", "en",
" ", " w", "es", " an", " i", "\r", "f ", "g", "p", "nd", " s", "nd ", "ed ",
"w", "ed", "http://", "for", "te", "ing", "y ", "The", " c", "ti", "r ", "his",
"st", " in", "ar", "nt", ",", " to", "y", "ng", " h", "with", "le", "al", "to ",
"b", "ou", "be", "were", " b", "se", "o ", "ent", "ha", "ng ", "their", "\"",
"hi", "from", " f", "in ", "de", "ion", "me", "v", ".", "ve", "all", "re ",
"ri", "ro", "is ", "co", "f t", "are", "ea", ". ", "her", " m", "er ", " p",
"es ", "by", "they", "di", "ra", "ic", "not", "s, ", "d t", "at ", "ce", "la",
"h ", "ne", "as ", "tio", "on ", "n t", "io", "we", " a ", "om", ", a", "s o",
"ur", "li", "ll", "ch", "had", "this", "e t", "g ", "e\r\n", " wh", "ere",
" co", "e o", "a ", "us", " d", "ss", "\n\r\n", "\r\n\r", "=\"", " be", " e",
"s a", "ma", "one", "t t", "or ", "but", "el", "so", "l ", "e s", "s,", "no",
"ter", " wa", "iv", "ho", "e a", " r", "hat", "s t", "ns", "ch ", "wh", "tr",
"ut", "/", "have", "ly ", "ta", " ha", " on", "tha", "-", " l", "ati", "en ",
"pe", " re", "there", "ass", "si", " fo", "wa", "ec", "our", "who", "its", "z",
"fo", "rs", ">", "ot", "un", "<", "im", "th ", "nc", "ate", "><", "ver", "ad",
" we", "ly", "ee", " n", "id", " cl", "ac", "il", "</", "rt", " wi", "div",
"e, ", " it", "whi", " ma", "ge", "x", "e c", "men", ".com"
};
static int smaz_compress(const char *in, int inlen, char *out, int outlen) {
unsigned int h1,h2,h3=0;
int verblen = 0, _outlen = outlen;
char verb[256], *_out = out;
while(inlen) {
int j = 7, needed;
char *flush = NULL;
const char *slot;
h1 = h2 = in[0]<<3;
if (inlen > 1) h2 += in[1];
if (inlen > 2) h3 = h2^in[2];
if (j > inlen) j = inlen;
/* Try to lookup substrings into the hash table, starting from the
* longer to the shorter substrings */
for (; j > 0; j--) {
switch(j) {
case 1: slot = Smaz_cb[h1%241]; break;
case 2: slot = Smaz_cb[h2%241]; break;
default: slot = Smaz_cb[h3%241]; break;
}
while(slot[0]) {
if (slot[0] == j && memcmp(slot+1,in,j) == 0) {
/* Match found in the hash table,
* prepare a verbatim bytes flush if needed */
if (verblen) {
needed = (verblen == 1) ? 2 : 2+verblen;
flush = out;
out += needed;
outlen -= needed;
}
/* Emit the byte */
if (outlen <= 0) return _outlen+1;
out[0] = slot[slot[0]+1];
out++;
outlen--;
inlen -= j;
in += j;
goto out;
} else {
slot += slot[0]+2;
}
}
}
/* Match not found - add the byte to the verbatim buffer */
verb[verblen] = in[0];
verblen++;
inlen--;
in++;
out:
/* Prepare a flush if we reached the flush length limit, and there
* is not already a pending flush operation. */
if (!flush && (verblen == 256 || (verblen > 0 && inlen == 0))) {
needed = (verblen == 1) ? 2 : 2+verblen;
flush = out;
out += needed;
outlen -= needed;
if (outlen < 0) return _outlen+1;
}
/* Perform a verbatim flush if needed */
if (flush) {
if (verblen == 1) {
flush[0] = (signed char)254;
flush[1] = verb[0];
} else {
flush[0] = (signed char)255;
flush[1] = (signed char)(verblen-1);
memcpy(flush+2,verb,verblen);
}
flush = NULL;
verblen = 0;
}
}
return out-_out;
}
static int smaz_decompress(const char *in, int inlen, char *out, int outlen) {
unsigned char *c = (unsigned char*) in;
char *_out = out;
int _outlen = outlen;
while(inlen) {
if (*c == 254) {
/* Verbatim byte */
if (outlen < 1) return _outlen+1;
*out = *(c+1);
out++;
outlen--;
c += 2;
inlen -= 2;
} else if (*c == 255) {
/* Verbatim string */
int len = (*(c+1))+1;
if (outlen < len) return _outlen+1;
memcpy(out,c+2,len);
out += len;
outlen -= len;
c += 2+len;
inlen -= 2+len;
} else {
/* Codebook entry */
const char *s = Smaz_rcb[*c];
int len = strlen(s);
if (outlen < len) return _outlen+1;
memcpy(out,s,len);
out += len;
outlen -= len;
c++;
inlen--;
}
}
return out-_out;
}
/////////// END OF SMAZ /////////////
struct _PHashTranslationCmp {
int orig_len;
@ -45,250 +251,284 @@ struct _PHashTranslationCmp {
void PHashTranslation::generate(const Ref<Translation> &p_from) {
#ifdef TOOLS_ENABLED
ERR_FAIL_COND(p_from.is_null());
List<StringName> keys;
p_from->get_message_list(&keys);
int size = Math::larger_prime(keys.size());
int size=Math::larger_prime(keys.size());
Vector<Vector<Pair<int, CharString> > > buckets;
Vector<Map<uint32_t, int> > table;
Vector<uint32_t> hfunc_table;
Vector<_PHashTranslationCmp> compressed;
print_line("compressing keys: "+itos(keys.size()));
Vector< Vector< Pair<int,CharString> > > buckets;
Vector< Map< uint32_t, int > > table;
Vector< uint32_t > hfunc_table;
Vector< _PHashTranslationCmp > compressed;
table.resize(size);
hfunc_table.resize(size);
buckets.resize(size);
compressed.resize(keys.size());
int idx = 0;
int total_compression_size = 0;
int total_string_size = 0;
int idx=0;
int total_compression_size=0;
int total_string_size=0;
for (List<StringName>::Element *E = keys.front(); E; E = E->next()) {
for(List<StringName>::Element *E=keys.front();E;E=E->next()) {
//hash string
CharString cs = E->get().operator String().utf8();
uint32_t h = hash(0, cs.get_data());
Pair<int, CharString> p;
p.first = idx;
p.second = cs;
buckets.write[h % size].push_back(p);
uint32_t h = hash(0,cs.get_data());
Pair<int,CharString> p;
p.first=idx;
p.second=cs;
buckets[h % size].push_back(p);
//compress string
CharString src_s = p_from->get_message(E->get()).operator String().utf8();
_PHashTranslationCmp ps;
ps.orig_len = src_s.size();
ps.offset = total_compression_size;
ps.orig_len=src_s.size();
ps.offset=total_compression_size;
if (ps.orig_len != 0) {
if (ps.orig_len!=0) {
CharString dst_s;
dst_s.resize(src_s.size());
int ret = smaz_compress(src_s.get_data(), src_s.size(), dst_s.ptrw(), src_s.size());
if (ret >= src_s.size()) {
int ret = smaz_compress(src_s.get_data(),src_s.size(),&dst_s[0],src_s.size());
if (ret>=src_s.size()) {
//if compressed is larger than original, just use original
ps.orig_len = src_s.size();
ps.compressed = src_s;
ps.orig_len=src_s.size();
ps.compressed=src_s;
} else {
dst_s.resize(ret);
//ps.orig_len=;
ps.compressed = dst_s;
ps.compressed=dst_s;
}
} else {
ps.orig_len = 1;
ps.orig_len=1;
ps.compressed.resize(1);
ps.compressed[0] = 0;
ps.compressed[0]=0;
}
compressed.write[idx] = ps;
total_compression_size += ps.compressed.size();
total_string_size += src_s.size();
compressed[idx]=ps;
total_compression_size+=ps.compressed.size();
total_string_size+=src_s.size();
idx++;
}
int bucket_table_size = 0;
int bucket_table_size=0;
print_line("total compressed string size: "+itos(total_compression_size)+" ("+itos(total_string_size)+" uncompressed).");
for (int i = 0; i < size; i++) {
for(int i=0;i<size;i++) {
const Vector<Pair<int, CharString> > &b = buckets[i];
Map<uint32_t, int> &t = table.write[i];
Vector< Pair<int,CharString> > &b = buckets[i];
Map< uint32_t, int > &t=table[i];
if (b.size() == 0)
if (b.size()==0)
continue;
//print_line("bucket: "+itos(i)+" - elements: "+itos(b.size()));
int d = 1;
int item = 0;
int item =0;
while (item < b.size()) {
while(item < b.size()) {
uint32_t slot = hash(d, b[item].second.get_data());
uint32_t slot = hash(d,b[item].second.get_data());
if (t.has(slot)) {
item = 0;
item=0;
d++;
t.clear();
} else {
t[slot] = b[item].first;
t[slot]=b[item].first;
item++;
}
}
hfunc_table.write[i] = d;
bucket_table_size += 2 + b.size() * 4;
hfunc_table[i]=d;
bucket_table_size+=2+b.size()*4;
}
ERR_FAIL_COND(bucket_table_size == 0);
print_line("bucket table size: "+itos(bucket_table_size*4));
print_line("hash table size: "+itos(size*4));
hash_table.resize(size);
bucket_table.resize(bucket_table_size);
PoolVector<int>::Write htwb = hash_table.write();
PoolVector<int>::Write btwb = bucket_table.write();
DVector<int>::Write htwb = hash_table.write();
DVector<int>::Write btwb = bucket_table.write();
uint32_t *htw = (uint32_t *)&htwb[0];
uint32_t *btw = (uint32_t *)&btwb[0];
uint32_t *htw = (uint32_t*)&htwb[0];
uint32_t *btw = (uint32_t*)&btwb[0];
int btindex = 0;
int collisions = 0;
int btindex=0;
int collisions=0;
for (int i = 0; i < size; i++) {
for(int i=0;i<size;i++) {
const Map<uint32_t, int> &t = table[i];
if (t.size() == 0) {
htw[i] = 0xFFFFFFFF; //nothing
Map< uint32_t, int > &t=table[i];
if (t.size()==0) {
htw[i]=0xFFFFFFFF; //nothing
continue;
} else if (t.size() > 1) {
collisions += t.size() - 1;
} else if (t.size()>1) {
collisions+=t.size()-1;
}
htw[i] = btindex;
btw[btindex++] = t.size();
btw[btindex++] = hfunc_table[i];
htw[i]=btindex;
btw[btindex++]=t.size();
btw[btindex++]=hfunc_table[i];
for (Map<uint32_t, int>::Element *E = t.front(); E; E = E->next()) {
for( Map< uint32_t, int >::Element *E=t.front();E;E=E->next()) {
btw[btindex++] = E->key();
btw[btindex++] = compressed[E->get()].offset;
btw[btindex++] = compressed[E->get()].compressed.size();
btw[btindex++] = compressed[E->get()].orig_len;
btw[btindex++]=E->key();
btw[btindex++]=compressed[E->get()].offset;
btw[btindex++]=compressed[E->get()].compressed.size();
btw[btindex++]=compressed[E->get()].orig_len;
}
}
print_line("total collisions: "+itos(collisions));
strings.resize(total_compression_size);
PoolVector<uint8_t>::Write cw = strings.write();
DVector<uint8_t>::Write cw = strings.write();
for (int i = 0; i < compressed.size(); i++) {
memcpy(&cw[compressed[i].offset], compressed[i].compressed.get_data(), compressed[i].compressed.size());
for(int i=0;i<compressed.size();i++) {
memcpy(&cw[compressed[i].offset],compressed[i].compressed.get_data(),compressed[i].compressed.size());
}
ERR_FAIL_COND(btindex != bucket_table_size);
ERR_FAIL_COND(btindex!=bucket_table_size);
set_locale(p_from->get_locale());
#endif
}
bool PHashTranslation::_set(const StringName &p_name, const Variant &p_value) {
bool PHashTranslation::_set(const StringName& p_name, const Variant& p_value) {
String name = p_name.operator String();
if (name == "hash_table") {
hash_table = p_value;
} else if (name == "bucket_table") {
bucket_table = p_value;
} else if (name == "strings") {
strings = p_value;
} else if (name == "load_from") {
if (name=="hash_table") {
hash_table=p_value;
print_line("translation: loaded hash table of size: "+itos(hash_table.size()));
} else if (name=="bucket_table") {
bucket_table=p_value;
print_line("translation: loaded bucket table of size: "+itos(bucket_table.size()));
} else if (name=="strings") {
strings=p_value;
print_line("translation: loaded string table of size: "+itos(strings.size()));
} else if (name=="load_from") {
print_line("generating");
generate(p_value);
} else
return false;
return true;
}
bool PHashTranslation::_get(const StringName &p_name, Variant &r_ret) const {
bool PHashTranslation::_get(const StringName& p_name,Variant &r_ret) const{
String name = p_name.operator String();
if (name == "hash_table")
r_ret = hash_table;
else if (name == "bucket_table")
r_ret = bucket_table;
else if (name == "strings")
r_ret = strings;
if (name=="hash_table")
r_ret=hash_table;
else if (name=="bucket_table")
r_ret=bucket_table;
else if (name=="strings")
r_ret=strings;
else
return false;
return true;
}
StringName PHashTranslation::get_message(const StringName &p_src_text) const {
StringName PHashTranslation::get_message(const StringName& p_src_text) const {
int htsize = hash_table.size();
if (htsize == 0)
if (htsize==0)
return StringName();
CharString str = p_src_text.operator String().utf8();
uint32_t h = hash(0, str.get_data());
uint32_t h = hash(0,str.get_data());
PoolVector<int>::Read htr = hash_table.read();
const uint32_t *htptr = (const uint32_t *)&htr[0];
PoolVector<int>::Read btr = bucket_table.read();
const uint32_t *btptr = (const uint32_t *)&btr[0];
PoolVector<uint8_t>::Read sr = strings.read();
const char *sptr = (const char *)&sr[0];
uint32_t p = htptr[h % htsize];
DVector<int>::Read htr = hash_table.read();
const uint32_t *htptr = (const uint32_t*)&htr[0];
DVector<int>::Read btr = bucket_table.read();
const uint32_t *btptr = (const uint32_t*)&btr[0];
DVector<uint8_t>::Read sr = strings.read();
const char *sptr= (const char*)&sr[0];
if (p == 0xFFFFFFFF) {
uint32_t p = htptr[ h % htsize];
//print_line("String: "+p_src_text.operator String());
//print_line("Hash: "+itos(p));
if (p==0xFFFFFFFF) {
// print_line("GETMSG: Nothing!");
return StringName(); //nothing
}
const Bucket &bucket = *(const Bucket *)&btptr[p];
const Bucket &bucket = *(const Bucket*)&btptr[p];
h = hash(bucket.func, str.get_data());
h = hash(bucket.func,str.get_data());
int idx = -1;
int idx=-1;
for (int i = 0; i < bucket.size; i++) {
for(int i=0;i<bucket.size;i++) {
if (bucket.elem[i].key == h) {
if (bucket.elem[i].key==h) {
idx = i;
idx=i;
break;
}
}
if (idx == -1) {
//print_line("bucket pos: "+itos(idx));
if (idx==-1) {
// print_line("GETMSG: Not in Bucket!");
return StringName();
}
if (bucket.elem[idx].comp_size == bucket.elem[idx].uncomp_size) {
String rstr;
rstr.parse_utf8(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].uncomp_size);
rstr.parse_utf8(&sptr[ bucket.elem[idx].str_offset ], bucket.elem[idx].uncomp_size );
// print_line("Uncompressed, size: "+itos(bucket.elem[idx].comp_size));
// print_line("Return: "+rstr);
return rstr;
} else {
CharString uncomp;
uncomp.resize(bucket.elem[idx].uncomp_size + 1);
smaz_decompress(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].comp_size, uncomp.ptrw(), bucket.elem[idx].uncomp_size);
uncomp.resize( bucket.elem[idx].uncomp_size+1 );
smaz_decompress(&sptr[ bucket.elem[idx].str_offset ], bucket.elem[idx].comp_size,uncomp.ptr(),bucket.elem[idx].uncomp_size );
String rstr;
rstr.parse_utf8(uncomp.get_data());
// print_line("Compressed, size: "+itos(bucket.elem[idx].comp_size));
// print_line("Return: "+rstr);
return rstr;
}
}
void PHashTranslation::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "hash_table"));
p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "bucket_table"));
p_list->push_back(PropertyInfo(Variant::POOL_BYTE_ARRAY, "strings"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "load_from", PROPERTY_HINT_RESOURCE_TYPE, "Translation", PROPERTY_USAGE_EDITOR));
void PHashTranslation::_get_property_list( List<PropertyInfo> *p_list) const{
p_list->push_back( PropertyInfo(Variant::INT_ARRAY, "hash_table"));
p_list->push_back( PropertyInfo(Variant::INT_ARRAY, "bucket_table"));
p_list->push_back( PropertyInfo(Variant::RAW_ARRAY, "strings"));
p_list->push_back( PropertyInfo(Variant::OBJECT, "load_from",PROPERTY_HINT_RESOURCE_TYPE,"Translation",PROPERTY_USAGE_EDITOR));
}
void PHashTranslation::_bind_methods() {
ClassDB::bind_method(D_METHOD("generate", "from"), &PHashTranslation::generate);
ObjectTypeDB::bind_method(_MD("generate","from:Translation"),&PHashTranslation::generate);
}
PHashTranslation::PHashTranslation() {
PHashTranslation::PHashTranslation()
{
}

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,25 +26,26 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef COMPRESSED_TRANSLATION_H
#define COMPRESSED_TRANSLATION_H
#include "core/translation.h"
#include "translation.h"
class PHashTranslation : public Translation {
GDCLASS(PHashTranslation, Translation);
OBJ_TYPE(PHashTranslation,Translation);
//this translation uses a sort of modified perfect hash algorithm
//it requires hashing strings twice and then does a binary search,
//it requieres 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
//load/store friendly types
PoolVector<int> hash_table;
PoolVector<int> bucket_table;
PoolVector<uint8_t> strings;
DVector<int> hash_table;
DVector<int> bucket_table;
DVector<uint8_t> strings;
struct Bucket {
@ -63,11 +63,11 @@ class PHashTranslation : public Translation {
Elem elem[1];
};
_FORCE_INLINE_ uint32_t hash(uint32_t d, const char *p_str) const {
_FORCE_INLINE_ uint32_t hash( uint32_t d, const char *p_str ) const {
if (d == 0)
d = 0x1000193;
while (*p_str) {
if (d==0)
d=0x1000193;
while(*p_str) {
d = (d * 0x1000193) ^ uint32_t(*p_str);
p_str++;
@ -75,15 +75,16 @@ class PHashTranslation : public Translation {
return d;
}
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
static void _bind_methods();
public:
virtual StringName get_message(const StringName &p_src_text) const; //overridable for other implementations
virtual StringName get_message(const StringName& p_src_text) const; //overridable for other implementations
void generate(const Ref<Translation> &p_from);
PHashTranslation();

View File

@ -1,308 +0,0 @@
"""Functions used to generate source files during build time
All such functions are invoked in a subprocess on Windows to prevent build flakiness.
"""
from platform_methods import subprocess_main
from compat import iteritems, itervalues, open_utf8, escape_string, byte_to_str
def make_certs_header(target, source, env):
src = source[0]
dst = target[0]
f = open(src, "rb")
g = open_utf8(dst, "w")
buf = f.read()
decomp_size = len(buf)
import zlib
buf = zlib.compress(buf)
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef _CERTS_RAW_H\n")
g.write("#define _CERTS_RAW_H\n")
# System certs path. Editor will use them if defined. (for package maintainers)
path = env["system_certs_path"]
g.write('#define _SYSTEM_CERTS_PATH "%s"\n' % str(path))
if env["builtin_certs"]:
# Defined here and not in env so changing it does not trigger a full rebuild.
g.write("#define BUILTIN_CERTS_ENABLED\n")
g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
g.write("static const unsigned char _certs_compressed[] = {\n")
for i in range(len(buf)):
g.write("\t" + byte_to_str(buf[i]) + ",\n")
g.write("};\n")
g.write("#endif")
g.close()
f.close()
def make_authors_header(target, source, env):
sections = ["Project Founders", "Lead Developer", "Project Manager", "Developers"]
sections_id = ["AUTHORS_FOUNDERS", "AUTHORS_LEAD_DEVELOPERS", "AUTHORS_PROJECT_MANAGERS", "AUTHORS_DEVELOPERS"]
src = source[0]
dst = target[0]
f = open_utf8(src, "r")
g = open_utf8(dst, "w")
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef _EDITOR_AUTHORS_H\n")
g.write("#define _EDITOR_AUTHORS_H\n")
reading = False
def close_section():
g.write("\t0\n")
g.write("};\n")
for line in f:
if reading:
if line.startswith(" "):
g.write('\t"' + escape_string(line.strip()) + '",\n')
continue
if line.startswith("## "):
if reading:
close_section()
reading = False
for section, section_id in zip(sections, sections_id):
if line.strip().endswith(section):
current_section = escape_string(section_id)
reading = True
g.write("const char *const " + current_section + "[] = {\n")
break
if reading:
close_section()
g.write("#endif\n")
g.close()
f.close()
def make_donors_header(target, source, env):
sections = [
"Platinum sponsors",
"Gold sponsors",
"Silver sponsors",
"Bronze sponsors",
"Mini sponsors",
"Gold donors",
"Silver donors",
"Bronze donors",
]
sections_id = [
"DONORS_SPONSOR_PLATINUM",
"DONORS_SPONSOR_GOLD",
"DONORS_SPONSOR_SILVER",
"DONORS_SPONSOR_BRONZE",
"DONORS_SPONSOR_MINI",
"DONORS_GOLD",
"DONORS_SILVER",
"DONORS_BRONZE",
]
src = source[0]
dst = target[0]
f = open_utf8(src, "r")
g = open_utf8(dst, "w")
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef _EDITOR_DONORS_H\n")
g.write("#define _EDITOR_DONORS_H\n")
reading = False
def close_section():
g.write("\t0\n")
g.write("};\n")
for line in f:
if reading >= 0:
if line.startswith(" "):
g.write('\t"' + escape_string(line.strip()) + '",\n')
continue
if line.startswith("## "):
if reading:
close_section()
reading = False
for section, section_id in zip(sections, sections_id):
if line.strip().endswith(section):
current_section = escape_string(section_id)
reading = True
g.write("const char *const " + current_section + "[] = {\n")
break
if reading:
close_section()
g.write("#endif\n")
g.close()
f.close()
def make_license_header(target, source, env):
src_copyright = source[0]
src_license = source[1]
dst = target[0]
class LicenseReader:
def __init__(self, license_file):
self._license_file = license_file
self.line_num = 0
self.current = self.next_line()
def next_line(self):
line = self._license_file.readline()
self.line_num += 1
while line.startswith("#"):
line = self._license_file.readline()
self.line_num += 1
self.current = line
return line
def next_tag(self):
if not ":" in self.current:
return ("", [])
tag, line = self.current.split(":", 1)
lines = [line.strip()]
while self.next_line() and self.current.startswith(" "):
lines.append(self.current.strip())
return (tag, lines)
from collections import OrderedDict
projects = OrderedDict()
license_list = []
with open_utf8(src_copyright, "r") as copyright_file:
reader = LicenseReader(copyright_file)
part = {}
while reader.current:
tag, content = reader.next_tag()
if tag in ("Files", "Copyright", "License"):
part[tag] = content[:]
elif tag == "Comment":
# attach part to named project
projects[content[0]] = projects.get(content[0], []) + [part]
if not tag or not reader.current:
# end of a paragraph start a new part
if "License" in part and not "Files" in part:
# no Files tag in this one, so assume standalone license
license_list.append(part["License"])
part = {}
reader.next_line()
data_list = []
for project in itervalues(projects):
for part in project:
part["file_index"] = len(data_list)
data_list += part["Files"]
part["copyright_index"] = len(data_list)
data_list += part["Copyright"]
with open_utf8(dst, "w") as f:
f.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
f.write("#ifndef _EDITOR_LICENSE_H\n")
f.write("#define _EDITOR_LICENSE_H\n")
f.write("const char *const GODOT_LICENSE_TEXT =")
with open_utf8(src_license, "r") as license_file:
for line in license_file:
escaped_string = escape_string(line.strip())
f.write('\n\t\t"' + escaped_string + '\\n"')
f.write(";\n\n")
f.write(
"struct ComponentCopyrightPart {\n"
"\tconst char *license;\n"
"\tconst char *const *files;\n"
"\tconst char *const *copyright_statements;\n"
"\tint file_count;\n"
"\tint copyright_count;\n"
"};\n\n"
)
f.write(
"struct ComponentCopyright {\n"
"\tconst char *name;\n"
"\tconst ComponentCopyrightPart *parts;\n"
"\tint part_count;\n"
"};\n\n"
)
f.write("const char *const COPYRIGHT_INFO_DATA[] = {\n")
for line in data_list:
f.write('\t"' + escape_string(line) + '",\n')
f.write("};\n\n")
f.write("const ComponentCopyrightPart COPYRIGHT_PROJECT_PARTS[] = {\n")
part_index = 0
part_indexes = {}
for project_name, project in iteritems(projects):
part_indexes[project_name] = part_index
for part in project:
f.write(
'\t{ "'
+ escape_string(part["License"][0])
+ '", '
+ "&COPYRIGHT_INFO_DATA["
+ str(part["file_index"])
+ "], "
+ "&COPYRIGHT_INFO_DATA["
+ str(part["copyright_index"])
+ "], "
+ str(len(part["Files"]))
+ ", "
+ str(len(part["Copyright"]))
+ " },\n"
)
part_index += 1
f.write("};\n\n")
f.write("const int COPYRIGHT_INFO_COUNT = " + str(len(projects)) + ";\n")
f.write("const ComponentCopyright COPYRIGHT_INFO[] = {\n")
for project_name, project in iteritems(projects):
f.write(
'\t{ "'
+ escape_string(project_name)
+ '", '
+ "&COPYRIGHT_PROJECT_PARTS["
+ str(part_indexes[project_name])
+ "], "
+ str(len(project))
+ " },\n"
)
f.write("};\n\n")
f.write("const int LICENSE_COUNT = " + str(len(license_list)) + ";\n")
f.write("const char *const LICENSE_NAMES[] = {\n")
for l in license_list:
f.write('\t"' + escape_string(l[0]) + '",\n')
f.write("};\n\n")
f.write("const char *const LICENSE_BODIES[] = {\n\n")
for l in license_list:
for line in l[1:]:
if line == ".":
f.write('\t"\\n"\n')
else:
f.write('\t"' + escape_string(line) + '\\n"\n')
f.write('\t"",\n\n')
f.write("};\n\n")
f.write("#endif\n")
if __name__ == "__main__":
subprocess_main(globals())

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,48 +26,23 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "core_string_names.h"
CoreStringNames *CoreStringNames::singleton = NULL;
CoreStringNames* CoreStringNames::singleton=NULL;
CoreStringNames::CoreStringNames() {
_free=StaticCString::create("free");
changed=StaticCString::create("changed");
_meta=StaticCString::create("__meta__");
_script=StaticCString::create("script/script");
script_changed=StaticCString::create("script_changed");
___pdcdata=StaticCString::create("___pdcdata");
__getvar=StaticCString::create("__getvar");
_iter_init=StaticCString::create("_iter_init");
_iter_next=StaticCString::create("_iter_next");
_iter_get=StaticCString::create("_iter_get");
get_rid=StaticCString::create("get_rid");
CoreStringNames::CoreStringNames() :
_free(StaticCString::create("free")),
changed(StaticCString::create("changed")),
_meta(StaticCString::create("__meta__")),
_script(StaticCString::create("script")),
script_changed(StaticCString::create("script_changed")),
___pdcdata(StaticCString::create("___pdcdata")),
__getvar(StaticCString::create("__getvar")),
_iter_init(StaticCString::create("_iter_init")),
_iter_next(StaticCString::create("_iter_next")),
_iter_get(StaticCString::create("_iter_get")),
get_rid(StaticCString::create("get_rid")),
_to_string(StaticCString::create("_to_string")),
#ifdef TOOLS_ENABLED
_sections_unfolded(StaticCString::create("_sections_unfolded")),
#endif
_custom_features(StaticCString::create("_custom_features")),
x(StaticCString::create("x")),
y(StaticCString::create("y")),
z(StaticCString::create("z")),
w(StaticCString::create("w")),
r(StaticCString::create("r")),
g(StaticCString::create("g")),
b(StaticCString::create("b")),
a(StaticCString::create("a")),
position(StaticCString::create("position")),
size(StaticCString::create("size")),
end(StaticCString::create("end")),
basis(StaticCString::create("basis")),
origin(StaticCString::create("origin")),
normal(StaticCString::create("normal")),
d(StaticCString::create("d")),
h(StaticCString::create("h")),
s(StaticCString::create("s")),
v(StaticCString::create("v")),
r8(StaticCString::create("r8")),
g8(StaticCString::create("g8")),
b8(StaticCString::create("b8")),
a8(StaticCString::create("a8")) {
}

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,29 +26,25 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef CORE_STRING_NAMES_H
#define CORE_STRING_NAMES_H
#include "core/string_name.h"
#include "string_db.h"
class CoreStringNames {
friend void register_core_types();
friend void unregister_core_types();
friend void register_core_types();
friend void unregister_core_types();
static CoreStringNames* singleton;
static void create() { singleton = memnew(CoreStringNames); }
static void free() {
memdelete(singleton);
singleton = NULL;
}
static void free() { memdelete( singleton); singleton=NULL; }
CoreStringNames();
public:
_FORCE_INLINE_ static CoreStringNames *get_singleton() { return singleton; }
_FORCE_INLINE_ static CoreStringNames* get_singleton() { return singleton; }
static CoreStringNames *singleton;
StringName _free;
StringName changed;
@ -62,34 +57,7 @@ public:
StringName _iter_next;
StringName _iter_get;
StringName get_rid;
StringName _to_string;
#ifdef TOOLS_ENABLED
StringName _sections_unfolded;
#endif
StringName _custom_features;
StringName x;
StringName y;
StringName z;
StringName w;
StringName r;
StringName g;
StringName b;
StringName a;
StringName position;
StringName size;
StringName end;
StringName basis;
StringName origin;
StringName normal;
StringName d;
StringName h;
StringName s;
StringName v;
StringName r8;
StringName g8;
StringName b8;
StringName a8;
};
#endif // SCENE_STRING_NAMES_H

View File

@ -1,391 +0,0 @@
/*************************************************************************/
/* cowdata.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 COWDATA_H_
#define COWDATA_H_
#include <string.h>
#include "core/error_macros.h"
#include "core/os/memory.h"
#include "core/safe_refcount.h"
template <class T>
class Vector;
class String;
class CharString;
template <class T, class V>
class VMap;
#if !defined(NO_THREADS)
SAFE_NUMERIC_TYPE_PUN_GUARANTEES(uint32_t)
#endif
template <class T>
class CowData {
template <class TV>
friend class Vector;
friend class String;
friend class CharString;
template <class TV, class VV>
friend class VMap;
private:
mutable T *_ptr;
// internal helpers
_FORCE_INLINE_ SafeNumeric<uint32_t> *_get_refcount() const {
if (!_ptr)
return NULL;
return reinterpret_cast<SafeNumeric<uint32_t> *>(_ptr) - 2;
}
_FORCE_INLINE_ uint32_t *_get_size() const {
if (!_ptr)
return NULL;
return reinterpret_cast<uint32_t *>(_ptr) - 1;
}
_FORCE_INLINE_ T *_get_data() const {
if (!_ptr)
return NULL;
return reinterpret_cast<T *>(_ptr);
}
_FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
//return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
return next_power_of_2(p_elements * sizeof(T));
}
_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
#if defined(_add_overflow) && defined(_mul_overflow)
size_t o;
size_t p;
if (_mul_overflow(p_elements, sizeof(T), &o)) {
*out = 0;
return false;
}
*out = next_power_of_2(o);
if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here
return true;
#else
// Speed is more important than correctness here, do the operations unchecked
// and hope the best
*out = _get_alloc_size(p_elements);
return true;
#endif
}
void _unref(void *p_data);
void _ref(const CowData *p_from);
void _ref(const CowData &p_from);
uint32_t _copy_on_write();
public:
void operator=(const CowData<T> &p_from) { _ref(p_from); }
_FORCE_INLINE_ T *ptrw() {
_copy_on_write();
return (T *)_get_data();
}
_FORCE_INLINE_ const T *ptr() const {
return _get_data();
}
_FORCE_INLINE_ int size() const {
uint32_t *size = (uint32_t *)_get_size();
if (size)
return *size;
else
return 0;
}
_FORCE_INLINE_ void clear() { resize(0); }
_FORCE_INLINE_ bool empty() const { return _ptr == 0; }
_FORCE_INLINE_ void set(int p_index, const T &p_elem) {
CRASH_BAD_INDEX(p_index, size());
_copy_on_write();
_get_data()[p_index] = p_elem;
}
_FORCE_INLINE_ T &get_m(int p_index) {
CRASH_BAD_INDEX(p_index, size());
_copy_on_write();
return _get_data()[p_index];
}
_FORCE_INLINE_ const T &get(int p_index) const {
CRASH_BAD_INDEX(p_index, size());
return _get_data()[p_index];
}
Error resize(int p_size);
_FORCE_INLINE_ void remove(int p_index) {
ERR_FAIL_INDEX(p_index, size());
T *p = ptrw();
int len = size();
for (int i = p_index; i < len - 1; i++) {
p[i] = p[i + 1];
};
resize(len - 1);
};
Error insert(int p_pos, const T &p_val) {
ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
resize(size() + 1);
for (int i = (size() - 1); i > p_pos; i--)
set(i, get(i - 1));
set(p_pos, p_val);
return OK;
};
int find(const T &p_val, int p_from = 0) const;
_FORCE_INLINE_ CowData();
_FORCE_INLINE_ ~CowData();
_FORCE_INLINE_ CowData(CowData<T> &p_from) { _ref(p_from); };
};
template <class T>
void CowData<T>::_unref(void *p_data) {
if (!p_data)
return;
SafeNumeric<uint32_t> *refc = _get_refcount();
if (refc->decrement() > 0)
return; // still in use
// clean up
if (!__has_trivial_destructor(T)) {
uint32_t *count = _get_size();
T *data = (T *)(count + 1);
for (uint32_t i = 0; i < *count; ++i) {
// call destructors
data[i].~T();
}
}
// free mem
Memory::free_static((uint8_t *)p_data, true);
}
template <class T>
uint32_t CowData<T>::_copy_on_write() {
if (!_ptr)
return 0;
SafeNumeric<uint32_t> *refc = _get_refcount();
uint32_t rc = refc->get();
if (likely(rc > 1)) {
/* in use by more than me */
uint32_t current_size = *_get_size();
uint32_t *mem_new = (uint32_t *)Memory::alloc_static(_get_alloc_size(current_size), true);
new (mem_new - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount
*(mem_new - 1) = current_size; //size
T *_data = (T *)(mem_new);
// initialize new elements
if (__has_trivial_copy(T)) {
memcpy(mem_new, _ptr, current_size * sizeof(T));
} else {
for (uint32_t i = 0; i < current_size; i++) {
memnew_placement(&_data[i], T(_get_data()[i]));
}
}
_unref(_ptr);
_ptr = _data;
rc = 1;
}
return rc;
}
template <class T>
Error CowData<T>::resize(int p_size) {
ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);
int current_size = size();
if (p_size == current_size)
return OK;
if (p_size == 0) {
// wants to clean up
_unref(_ptr);
_ptr = NULL;
return OK;
}
// possibly changing size, copy on write
uint32_t rc = _copy_on_write();
size_t current_alloc_size = _get_alloc_size(current_size);
size_t alloc_size;
ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
if (p_size > current_size) {
if (alloc_size != current_alloc_size) {
if (current_size == 0) {
// alloc from scratch
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
*(ptr - 1) = 0; //size, currently none
new (ptr - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount
_ptr = (T *)ptr;
} else {
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount
_ptr = (T *)(_ptrnew);
}
}
// construct the newly created elements
if (!__has_trivial_constructor(T)) {
T *elems = _get_data();
for (int i = *_get_size(); i < p_size; i++) {
memnew_placement(&elems[i], T);
}
}
*_get_size() = p_size;
} else if (p_size < current_size) {
if (!__has_trivial_destructor(T)) {
// deinitialize no longer needed elements
for (uint32_t i = p_size; i < *_get_size(); i++) {
T *t = &_get_data()[i];
t->~T();
}
}
if (alloc_size != current_alloc_size) {
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount
_ptr = (T *)(_ptrnew);
}
*_get_size() = p_size;
}
return OK;
}
template <class T>
int CowData<T>::find(const T &p_val, int p_from) const {
int ret = -1;
if (p_from < 0 || size() == 0) {
return ret;
}
for (int i = p_from; i < size(); i++) {
if (get(i) == p_val) {
ret = i;
break;
}
}
return ret;
}
template <class T>
void CowData<T>::_ref(const CowData *p_from) {
_ref(*p_from);
}
template <class T>
void CowData<T>::_ref(const CowData &p_from) {
if (_ptr == p_from._ptr)
return; // self assign, do nothing.
_unref(_ptr);
_ptr = NULL;
if (!p_from._ptr)
return; //nothing to do
if (p_from._get_refcount()->conditional_increment() > 0) { // could reference
_ptr = p_from._ptr;
}
}
template <class T>
CowData<T>::CowData() {
_ptr = NULL;
}
template <class T>
CowData<T>::~CowData() {
_unref(_ptr);
}
#endif /* COW_H_ */

View File

@ -1,51 +0,0 @@
#!/usr/bin/env python
Import("env")
env_crypto = env.Clone()
is_builtin = env["builtin_mbedtls"]
has_module = env["module_mbedtls_enabled"]
thirdparty_obj = []
if is_builtin or not has_module:
# Use our headers for builtin or if the module is not going to be compiled.
# We decided not to depend on system mbedtls just for these few files that can
# be easily extracted.
env_crypto.Prepend(CPPPATH=["#thirdparty/mbedtls/include"])
# MbedTLS core functions (for CryptoCore).
# If the mbedtls module is compiled we don't need to add the .c files with our
# custom config since they will be built by the module itself.
# Only if the module is not enabled, we must compile here the required sources
# to make a "light" build with only the necessary mbedtls files.
if not has_module:
env_thirdparty = env_crypto.Clone()
env_thirdparty.disable_warnings()
# Custom config file
env_thirdparty.Append(
CPPDEFINES=[("MBEDTLS_CONFIG_FILE", '\\"thirdparty/mbedtls/include/godot_core_mbedtls_config.h\\"')]
)
thirdparty_mbedtls_dir = "#thirdparty/mbedtls/library/"
thirdparty_mbedtls_sources = [
"aes.c",
"base64.c",
"md5.c",
"sha1.c",
"sha256.c",
"godot_core_mbedtls_platform.c",
]
thirdparty_mbedtls_sources = [thirdparty_mbedtls_dir + file for file in thirdparty_mbedtls_sources]
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_mbedtls_sources)
env.core_sources += thirdparty_obj
# Godot source files
core_obj = []
env_crypto.add_source_files(core_obj, "*.cpp")
env.core_sources += core_obj
# Needed to force rebuilding the core files when the thirdparty library is updated.
env.Depends(core_obj, thirdparty_obj)

View File

@ -1,158 +0,0 @@
/*************************************************************************/
/* crypto.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 "crypto.h"
#include "core/engine.h"
#include "core/io/certs_compressed.gen.h"
#include "core/io/compression.h"
/// Resources
CryptoKey *(*CryptoKey::_create)() = NULL;
CryptoKey *CryptoKey::create() {
if (_create)
return _create();
return NULL;
}
void CryptoKey::_bind_methods() {
ClassDB::bind_method(D_METHOD("save", "path"), &CryptoKey::save);
ClassDB::bind_method(D_METHOD("load", "path"), &CryptoKey::load);
}
X509Certificate *(*X509Certificate::_create)() = NULL;
X509Certificate *X509Certificate::create() {
if (_create)
return _create();
return NULL;
}
void X509Certificate::_bind_methods() {
ClassDB::bind_method(D_METHOD("save", "path"), &X509Certificate::save);
ClassDB::bind_method(D_METHOD("load", "path"), &X509Certificate::load);
}
/// Crypto
void (*Crypto::_load_default_certificates)(String p_path) = NULL;
Crypto *(*Crypto::_create)() = NULL;
Crypto *Crypto::create() {
if (_create)
return _create();
ERR_FAIL_V_MSG(NULL, "Crypto is not available when the mbedtls module is disabled.");
}
void Crypto::load_default_certificates(String p_path) {
if (_load_default_certificates)
_load_default_certificates(p_path);
}
void Crypto::_bind_methods() {
ClassDB::bind_method(D_METHOD("generate_random_bytes", "size"), &Crypto::generate_random_bytes);
ClassDB::bind_method(D_METHOD("generate_rsa", "size"), &Crypto::generate_rsa);
ClassDB::bind_method(D_METHOD("generate_self_signed_certificate", "key", "issuer_name", "not_before", "not_after"), &Crypto::generate_self_signed_certificate, DEFVAL("CN=myserver,O=myorganisation,C=IT"), DEFVAL("20140101000000"), DEFVAL("20340101000000"));
}
Crypto::Crypto() {
}
/// Resource loader/saver
RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error) {
String el = p_path.get_extension().to_lower();
if (el == "crt") {
X509Certificate *cert = X509Certificate::create();
if (cert)
cert->load(p_path);
return cert;
} else if (el == "key") {
CryptoKey *key = CryptoKey::create();
if (key)
key->load(p_path);
return key;
}
return NULL;
}
void ResourceFormatLoaderCrypto::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("crt");
p_extensions->push_back("key");
}
bool ResourceFormatLoaderCrypto::handles_type(const String &p_type) const {
return p_type == "X509Certificate" || p_type == "CryptoKey";
}
String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const {
String el = p_path.get_extension().to_lower();
if (el == "crt")
return "X509Certificate";
else if (el == "key")
return "CryptoKey";
return "";
}
Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
Error err;
Ref<X509Certificate> cert = p_resource;
Ref<CryptoKey> key = p_resource;
if (cert.is_valid()) {
err = cert->save(p_path);
} else if (key.is_valid()) {
err = key->save(p_path);
} else {
ERR_FAIL_V(ERR_INVALID_PARAMETER);
}
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save Crypto resource to file '" + p_path + "'.");
return OK;
}
void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
const X509Certificate *cert = Object::cast_to<X509Certificate>(*p_resource);
const CryptoKey *key = Object::cast_to<CryptoKey>(*p_resource);
if (cert) {
p_extensions->push_back("crt");
}
if (key) {
p_extensions->push_back("key");
}
}
bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const {
return Object::cast_to<X509Certificate>(*p_resource) || Object::cast_to<CryptoKey>(*p_resource);
}

View File

@ -1,101 +0,0 @@
/*************************************************************************/
/* crypto.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 CRYPTO_H
#define CRYPTO_H
#include "core/reference.h"
#include "core/resource.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
class CryptoKey : public Resource {
GDCLASS(CryptoKey, Resource);
protected:
static void _bind_methods();
static CryptoKey *(*_create)();
public:
static CryptoKey *create();
virtual Error load(String p_path) = 0;
virtual Error save(String p_path) = 0;
};
class X509Certificate : public Resource {
GDCLASS(X509Certificate, Resource);
protected:
static void _bind_methods();
static X509Certificate *(*_create)();
public:
static X509Certificate *create();
virtual Error load(String p_path) = 0;
virtual Error load_from_memory(const uint8_t *p_buffer, int p_len) = 0;
virtual Error save(String p_path) = 0;
};
class Crypto : public Reference {
GDCLASS(Crypto, Reference);
protected:
static void _bind_methods();
static Crypto *(*_create)();
static void (*_load_default_certificates)(String p_path);
public:
static Crypto *create();
static void load_default_certificates(String p_path);
virtual PoolByteArray generate_random_bytes(int p_bytes) = 0;
virtual Ref<CryptoKey> generate_rsa(int p_bytes) = 0;
virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) = 0;
Crypto();
};
class ResourceFormatLoaderCrypto : public ResourceFormatLoader {
public:
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
class ResourceFormatSaverCrypto : public ResourceFormatSaver {
public:
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
virtual bool recognize(const RES &p_resource) const;
};
#endif // CRYPTO_H

View File

@ -1,183 +0,0 @@
/*************************************************************************/
/* crypto_core.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 "crypto_core.h"
#include <mbedtls/aes.h>
#include <mbedtls/base64.h>
#include <mbedtls/md5.h>
#include <mbedtls/sha1.h>
#include <mbedtls/sha256.h>
// MD5
CryptoCore::MD5Context::MD5Context() {
ctx = memalloc(sizeof(mbedtls_md5_context));
mbedtls_md5_init((mbedtls_md5_context *)ctx);
}
CryptoCore::MD5Context::~MD5Context() {
mbedtls_md5_free((mbedtls_md5_context *)ctx);
memfree((mbedtls_md5_context *)ctx);
}
Error CryptoCore::MD5Context::start() {
int ret = mbedtls_md5_starts_ret((mbedtls_md5_context *)ctx);
return ret ? FAILED : OK;
}
Error CryptoCore::MD5Context::update(const uint8_t *p_src, size_t p_len) {
int ret = mbedtls_md5_update_ret((mbedtls_md5_context *)ctx, p_src, p_len);
return ret ? FAILED : OK;
}
Error CryptoCore::MD5Context::finish(unsigned char r_hash[16]) {
int ret = mbedtls_md5_finish_ret((mbedtls_md5_context *)ctx, r_hash);
return ret ? FAILED : OK;
}
// SHA1
CryptoCore::SHA1Context::SHA1Context() {
ctx = memalloc(sizeof(mbedtls_sha1_context));
mbedtls_sha1_init((mbedtls_sha1_context *)ctx);
}
CryptoCore::SHA1Context::~SHA1Context() {
mbedtls_sha1_free((mbedtls_sha1_context *)ctx);
memfree((mbedtls_sha1_context *)ctx);
}
Error CryptoCore::SHA1Context::start() {
int ret = mbedtls_sha1_starts_ret((mbedtls_sha1_context *)ctx);
return ret ? FAILED : OK;
}
Error CryptoCore::SHA1Context::update(const uint8_t *p_src, size_t p_len) {
int ret = mbedtls_sha1_update_ret((mbedtls_sha1_context *)ctx, p_src, p_len);
return ret ? FAILED : OK;
}
Error CryptoCore::SHA1Context::finish(unsigned char r_hash[20]) {
int ret = mbedtls_sha1_finish_ret((mbedtls_sha1_context *)ctx, r_hash);
return ret ? FAILED : OK;
}
// SHA256
CryptoCore::SHA256Context::SHA256Context() {
ctx = memalloc(sizeof(mbedtls_sha256_context));
mbedtls_sha256_init((mbedtls_sha256_context *)ctx);
}
CryptoCore::SHA256Context::~SHA256Context() {
mbedtls_sha256_free((mbedtls_sha256_context *)ctx);
memfree((mbedtls_sha256_context *)ctx);
}
Error CryptoCore::SHA256Context::start() {
int ret = mbedtls_sha256_starts_ret((mbedtls_sha256_context *)ctx, 0);
return ret ? FAILED : OK;
}
Error CryptoCore::SHA256Context::update(const uint8_t *p_src, size_t p_len) {
int ret = mbedtls_sha256_update_ret((mbedtls_sha256_context *)ctx, p_src, p_len);
return ret ? FAILED : OK;
}
Error CryptoCore::SHA256Context::finish(unsigned char r_hash[32]) {
int ret = mbedtls_sha256_finish_ret((mbedtls_sha256_context *)ctx, r_hash);
return ret ? FAILED : OK;
}
// AES256
CryptoCore::AESContext::AESContext() {
ctx = memalloc(sizeof(mbedtls_aes_context));
mbedtls_aes_init((mbedtls_aes_context *)ctx);
}
CryptoCore::AESContext::~AESContext() {
mbedtls_aes_free((mbedtls_aes_context *)ctx);
memfree((mbedtls_aes_context *)ctx);
}
Error CryptoCore::AESContext::set_encode_key(const uint8_t *p_key, size_t p_bits) {
int ret = mbedtls_aes_setkey_enc((mbedtls_aes_context *)ctx, p_key, p_bits);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::set_decode_key(const uint8_t *p_key, size_t p_bits) {
int ret = mbedtls_aes_setkey_dec((mbedtls_aes_context *)ctx, p_key, p_bits);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) {
int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_src, r_dst);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) {
int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_src, r_dst);
return ret ? FAILED : OK;
}
// CryptoCore
String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) {
int b64len = p_src_len / 3 * 4 + 4 + 1;
PoolVector<uint8_t> b64buff;
b64buff.resize(b64len);
PoolVector<uint8_t>::Write w64 = b64buff.write();
size_t strlen = 0;
int ret = b64_encode(&w64[0], b64len, &strlen, p_src, p_src_len);
w64[strlen] = 0;
return ret ? String() : (const char *)&w64[0];
}
Error CryptoCore::b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) {
int ret = mbedtls_base64_encode(r_dst, p_dst_len, r_len, p_src, p_src_len);
return ret ? FAILED : OK;
}
Error CryptoCore::b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) {
int ret = mbedtls_base64_decode(r_dst, p_dst_len, r_len, p_src, p_src_len);
return ret ? FAILED : OK;
}
Error CryptoCore::md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]) {
int ret = mbedtls_md5_ret(p_src, p_src_len, r_hash);
return ret ? FAILED : OK;
}
Error CryptoCore::sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]) {
int ret = mbedtls_sha1_ret(p_src, p_src_len, r_hash);
return ret ? FAILED : OK;
}
Error CryptoCore::sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]) {
int ret = mbedtls_sha256_ret(p_src, p_src_len, r_hash, 0);
return ret ? FAILED : OK;
}

View File

@ -1,104 +0,0 @@
/*************************************************************************/
/* crypto_core.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 CRYPTO_CORE_H
#define CRYPTO_CORE_H
#include "core/reference.h"
class CryptoCore {
public:
class MD5Context {
private:
void *ctx; // To include, or not to include...
public:
MD5Context();
~MD5Context();
Error start();
Error update(const uint8_t *p_src, size_t p_len);
Error finish(unsigned char r_hash[16]);
};
class SHA1Context {
private:
void *ctx; // To include, or not to include...
public:
SHA1Context();
~SHA1Context();
Error start();
Error update(const uint8_t *p_src, size_t p_len);
Error finish(unsigned char r_hash[20]);
};
class SHA256Context {
private:
void *ctx; // To include, or not to include...
public:
SHA256Context();
~SHA256Context();
Error start();
Error update(const uint8_t *p_src, size_t p_len);
Error finish(unsigned char r_hash[32]);
};
class AESContext {
private:
void *ctx; // To include, or not to include...
public:
AESContext();
~AESContext();
Error set_encode_key(const uint8_t *p_key, size_t p_bits);
Error set_decode_key(const uint8_t *p_key, size_t p_bits);
Error encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]);
Error decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]);
};
static String b64_encode_str(const uint8_t *p_src, int p_src_len);
static Error b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len);
static Error b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len);
static Error md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]);
static Error sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]);
static Error sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]);
};
#endif // CRYPTO_CORE_H

View File

@ -1,138 +0,0 @@
/*************************************************************************/
/* hashing_context.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 "hashing_context.h"
#include "core/crypto/crypto_core.h"
Error HashingContext::start(HashType p_type) {
ERR_FAIL_COND_V(ctx != NULL, ERR_ALREADY_IN_USE);
_create_ctx(p_type);
ERR_FAIL_COND_V(ctx == NULL, ERR_UNAVAILABLE);
switch (type) {
case HASH_MD5:
return ((CryptoCore::MD5Context *)ctx)->start();
case HASH_SHA1:
return ((CryptoCore::SHA1Context *)ctx)->start();
case HASH_SHA256:
return ((CryptoCore::SHA256Context *)ctx)->start();
}
return ERR_UNAVAILABLE;
}
Error HashingContext::update(PoolByteArray p_chunk) {
ERR_FAIL_COND_V(ctx == NULL, ERR_UNCONFIGURED);
size_t len = p_chunk.size();
ERR_FAIL_COND_V(len == 0, FAILED);
PoolByteArray::Read r = p_chunk.read();
switch (type) {
case HASH_MD5:
return ((CryptoCore::MD5Context *)ctx)->update(&r[0], len);
case HASH_SHA1:
return ((CryptoCore::SHA1Context *)ctx)->update(&r[0], len);
case HASH_SHA256:
return ((CryptoCore::SHA256Context *)ctx)->update(&r[0], len);
}
return ERR_UNAVAILABLE;
}
PoolByteArray HashingContext::finish() {
ERR_FAIL_COND_V(ctx == NULL, PoolByteArray());
PoolByteArray out;
Error err = FAILED;
switch (type) {
case HASH_MD5:
out.resize(16);
err = ((CryptoCore::MD5Context *)ctx)->finish(out.write().ptr());
break;
case HASH_SHA1:
out.resize(20);
err = ((CryptoCore::SHA1Context *)ctx)->finish(out.write().ptr());
break;
case HASH_SHA256:
out.resize(32);
err = ((CryptoCore::SHA256Context *)ctx)->finish(out.write().ptr());
break;
}
_delete_ctx();
ERR_FAIL_COND_V(err != OK, PoolByteArray());
return out;
}
void HashingContext::_create_ctx(HashType p_type) {
type = p_type;
switch (type) {
case HASH_MD5:
ctx = memnew(CryptoCore::MD5Context);
break;
case HASH_SHA1:
ctx = memnew(CryptoCore::SHA1Context);
break;
case HASH_SHA256:
ctx = memnew(CryptoCore::SHA256Context);
break;
default:
ctx = NULL;
}
}
void HashingContext::_delete_ctx() {
switch (type) {
case HASH_MD5:
memdelete((CryptoCore::MD5Context *)ctx);
break;
case HASH_SHA1:
memdelete((CryptoCore::SHA1Context *)ctx);
break;
case HASH_SHA256:
memdelete((CryptoCore::SHA256Context *)ctx);
break;
}
ctx = NULL;
}
void HashingContext::_bind_methods() {
ClassDB::bind_method(D_METHOD("start", "type"), &HashingContext::start);
ClassDB::bind_method(D_METHOD("update", "chunk"), &HashingContext::update);
ClassDB::bind_method(D_METHOD("finish"), &HashingContext::finish);
BIND_ENUM_CONSTANT(HASH_MD5);
BIND_ENUM_CONSTANT(HASH_SHA1);
BIND_ENUM_CONSTANT(HASH_SHA256);
}
HashingContext::HashingContext() {
ctx = NULL;
}
HashingContext::~HashingContext() {
if (ctx != NULL)
_delete_ctx();
}

View File

@ -1,66 +0,0 @@
/*************************************************************************/
/* hashing_context.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 HASHING_CONTEXT_H
#define HASHING_CONTEXT_H
#include "core/reference.h"
class HashingContext : public Reference {
GDCLASS(HashingContext, Reference);
public:
enum HashType {
HASH_MD5,
HASH_SHA1,
HASH_SHA256
};
private:
void *ctx;
HashType type;
protected:
static void _bind_methods();
void _create_ctx(HashType p_type);
void _delete_ctx();
public:
Error start(HashType p_type);
Error update(PoolByteArray p_chunk);
PoolByteArray finish();
HashingContext();
~HashingContext();
};
VARIANT_ENUM_CAST(HashingContext::HashType);
#endif // HASHING_CONTEXT_H

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,259 +26,206 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "dictionary.h"
#include "safe_refcount.h"
#include "variant.h"
#include "io/json.h"
struct _DictionaryVariantHash {
static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); }
};
#include "core/ordered_hash_map.h"
#include "core/safe_refcount.h"
#include "core/variant.h"
struct DictionaryPrivate {
SafeRefCount refcount;
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> variant_map;
HashMap<Variant,Variant,_DictionaryVariantHash> variant_map;
bool shared;
};
void Dictionary::get_key_list(List<Variant> *p_keys) const {
if (_p->variant_map.empty())
void Dictionary::get_key_list( List<Variant> *p_keys) const {
_p->variant_map.get_key_list(p_keys);
}
void Dictionary::_copy_on_write() const {
//make a copy of what we have
if (_p->shared)
return;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
p_keys->push_back(E.key());
}
DictionaryPrivate *p = memnew(DictionaryPrivate);
p->shared=_p->shared;
p->variant_map=_p->variant_map;
p->refcount.init();
_unref();
_p=p;
}
Variant Dictionary::get_key_at_index(int p_index) const {
Variant& Dictionary::operator[](const Variant& p_key) {
int index = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
if (index == p_index) {
return E.key();
}
index++;
}
return Variant();
}
Variant Dictionary::get_value_at_index(int p_index) const {
int index = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
if (index == p_index) {
return E.value();
}
index++;
}
return Variant();
}
Variant &Dictionary::operator[](const Variant &p_key) {
_copy_on_write();
return _p->variant_map[p_key];
}
const Variant &Dictionary::operator[](const Variant &p_key) const {
const Variant& Dictionary::operator[](const Variant& p_key) const {
return _p->variant_map[p_key];
}
const Variant *Dictionary::getptr(const Variant &p_key) const {
const Variant* Dictionary::getptr(const Variant& p_key) const {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
return _p->variant_map.getptr(p_key);
}
Variant* Dictionary::getptr(const Variant& p_key) {
if (!E)
return NULL;
return &E.get();
_copy_on_write();
return _p->variant_map.getptr(p_key);
}
Variant *Dictionary::getptr(const Variant &p_key) {
Variant Dictionary::get_valid(const Variant& p_key) const {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(p_key);
if (!E)
return NULL;
return &E.get();
}
Variant Dictionary::get_valid(const Variant &p_key) const {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
if (!E)
const Variant *v = getptr(p_key);
if (!v)
return Variant();
return E.get();
return *v;
}
Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const {
const Variant *result = getptr(p_key);
if (!result) {
return p_default;
}
return *result;
}
int Dictionary::size() const {
return _p->variant_map.size();
}
bool Dictionary::empty() const {
return !_p->variant_map.size();
}
bool Dictionary::has(const Variant &p_key) const {
bool Dictionary::has(const Variant& p_key) const {
return _p->variant_map.has(p_key);
}
bool Dictionary::has_all(const Array &p_keys) const {
for (int i = 0; i < p_keys.size(); i++) {
if (!has(p_keys[i])) {
return false;
}
}
return true;
void Dictionary::erase(const Variant& p_key) {
_copy_on_write();
_p->variant_map.erase(p_key);
}
bool Dictionary::erase(const Variant &p_key) {
bool Dictionary::operator==(const Dictionary& p_dictionary) const {
return _p->variant_map.erase(p_key);
return _p==p_dictionary._p;
}
bool Dictionary::operator==(const Dictionary &p_dictionary) const {
return _p == p_dictionary._p;
}
bool Dictionary::operator!=(const Dictionary &p_dictionary) const {
return _p != p_dictionary._p;
}
void Dictionary::_ref(const Dictionary &p_from) const {
void Dictionary::_ref(const Dictionary& p_from) const {
//make a copy first (thread safe)
if (!p_from._p->refcount.ref())
return; // couldn't copy
//if this is the same, unreference the other one
if (p_from._p == _p) {
if (p_from._p==_p) {
_p->refcount.unref();
return;
}
if (_p)
_unref();
_p = p_from._p;
_p=p_from._p;
}
void Dictionary::clear() {
_copy_on_write();
_p->variant_map.clear();
}
bool Dictionary::is_shared() const {
return _p->shared;
}
void Dictionary::_unref() const {
ERR_FAIL_COND(!_p);
if (_p->refcount.unref()) {
memdelete(_p);
}
_p = NULL;
_p=NULL;
}
uint32_t Dictionary::hash() const {
uint32_t h = hash_djb2_one_32(Variant::DICTIONARY);
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
h = hash_djb2_one_32(E.key().hash(), h);
h = hash_djb2_one_32(E.value().hash(), h);
}
return h;
return hash_djb2_one_64(make_uint64_t(_p));
}
Array Dictionary::keys() const {
Array varr;
if (_p->variant_map.empty())
return varr;
varr.resize(size());
int i = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
varr[i] = E.key();
i++;
Array karr;
karr.resize(size());
const Variant *K=NULL;
int idx=0;
while((K=next(K))) {
karr[idx++]=(*K);
}
return karr;
return varr;
}
Array Dictionary::values() const {
const Variant* Dictionary::next(const Variant* p_key) const {
Array varr;
if (_p->variant_map.empty())
return varr;
varr.resize(size());
int i = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
varr[i] = E.get();
i++;
}
return varr;
return _p->variant_map.next(p_key);
}
const Variant *Dictionary::next(const Variant *p_key) const {
if (p_key == NULL) {
// caller wants to get the first element
if (_p->variant_map.front())
return &_p->variant_map.front().key();
return NULL;
}
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(*p_key);
Error Dictionary::parse_json(const String& p_json) {
if (E && E.next())
return &E.next().key();
return NULL;
}
Dictionary Dictionary::duplicate(bool p_deep) const {
Dictionary n;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
n[E.key()] = p_deep ? E.value().duplicate(true) : E.value();
String errstr;
int errline=0;
if (p_json != ""){
Error err = JSON::parse(p_json,*this,errstr,errline);
if (err!=OK) {
ERR_EXPLAIN("Error parsing JSON: "+errstr+" at line: "+itos(errline));
ERR_FAIL_COND_V(err!=OK,err);
}
}
return n;
return OK;
}
void Dictionary::operator=(const Dictionary &p_dictionary) {
String Dictionary::to_json() const {
return JSON::print(*this);
}
void Dictionary::operator=(const Dictionary& p_dictionary) {
_ref(p_dictionary);
}
const void *Dictionary::id() const {
return _p->variant_map.id();
}
Dictionary::Dictionary(const Dictionary &p_from) {
_p = NULL;
Dictionary::Dictionary(const Dictionary& p_from) {
_p=NULL;
_ref(p_from);
}
Dictionary::Dictionary() {
_p = memnew(DictionaryPrivate);
Dictionary::Dictionary(bool p_shared) {
_p=memnew( DictionaryPrivate );
_p->refcount.init();
_p->shared=p_shared;
}
Dictionary::~Dictionary() {
_unref();
}

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,65 +26,62 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef DICTIONARY_H
#define DICTIONARY_H
#include "core/array.h"
#include "core/list.h"
#include "core/ustring.h"
#include "list.h"
#include "array.h"
#include "ustring.h"
class Variant;
struct DictionaryPrivate;
class Dictionary {
mutable DictionaryPrivate *_p;
void _ref(const Dictionary &p_from) const;
void _copy_on_write() const;
void _ref(const Dictionary& p_from) const;
void _unref() const;
public:
void get_key_list(List<Variant> *p_keys) const;
Variant get_key_at_index(int p_index) const;
Variant get_value_at_index(int p_index) const;
Variant &operator[](const Variant &p_key);
const Variant &operator[](const Variant &p_key) const;
void get_key_list( List<Variant> *p_keys) const;
const Variant *getptr(const Variant &p_key) const;
Variant *getptr(const Variant &p_key);
Variant& operator[](const Variant& p_key);
const Variant& operator[](const Variant& p_key) const;
Variant get_valid(const Variant &p_key) const;
Variant get(const Variant &p_key, const Variant &p_default) const;
const Variant* getptr(const Variant& p_key) const;
Variant* getptr(const Variant& p_key);
Variant get_valid(const Variant& p_key) const;
int size() const;
bool empty() const;
void clear();
bool has(const Variant &p_key) const;
bool has_all(const Array &p_keys) const;
bool erase(const Variant &p_key);
Error parse_json(const String& p_json);
String to_json() const;
bool operator==(const Dictionary &p_dictionary) const;
bool operator!=(const Dictionary &p_dictionary) const;
bool is_shared() const;
bool has(const Variant& p_key) const;
void erase(const Variant& p_key);
bool operator==(const Dictionary& p_dictionary) const;
uint32_t hash() const;
void operator=(const Dictionary &p_dictionary);
void operator=(const Dictionary& p_dictionary);
const Variant *next(const Variant *p_key = NULL) const;
const Variant* next(const Variant* p_key=NULL) const;
Array keys() const;
Array values() const;
Dictionary duplicate(bool p_deep = false) const;
const void *id() const;
Dictionary(const Dictionary &p_from);
Dictionary();
Dictionary(const Dictionary& p_from);
Dictionary(bool p_shared=false);
~Dictionary();
};

32
core/dvector.cpp Normal file
View File

@ -0,0 +1,32 @@
/*************************************************************************/
/* dvector.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 "dvector.h"
Mutex* dvector_lock=NULL;

429
core/dvector.h Normal file
View File

@ -0,0 +1,429 @@
/*************************************************************************/
/* dvector.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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 DVECTOR_H
#define DVECTOR_H
#include "os/memory.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
extern Mutex* dvector_lock;
template<class T>
class DVector {
mutable MID mem;
void copy_on_write() {
if (!mem.is_valid())
return;
if (dvector_lock)
dvector_lock->lock();
MID_Lock lock( mem );
if ( *(int*)lock.data() == 1 ) {
// one reference, means no refcount changes
if (dvector_lock)
dvector_lock->unlock();
return;
}
MID new_mem= dynalloc( mem.get_size() );
if (!new_mem.is_valid()) {
if (dvector_lock)
dvector_lock->unlock();
ERR_FAIL_COND( new_mem.is_valid() ); // out of memory
}
MID_Lock dst_lock( new_mem );
int *rc = (int*)dst_lock.data();
*rc=1;
T * dst = (T*)(rc + 1 );
T * src =(T*) ((int*)lock.data() + 1 );
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
for (int i=0;i<count;i++) {
memnew_placement( &dst[i], T(src[i]) );
}
(*(int*)lock.data())--;
// unlock all
dst_lock=MID_Lock();
lock=MID_Lock();
mem=new_mem;
if (dvector_lock)
dvector_lock->unlock();
}
void reference( const DVector& p_dvector ) {
unreference();
if (dvector_lock)
dvector_lock->lock();
if (!p_dvector.mem.is_valid()) {
if (dvector_lock)
dvector_lock->unlock();
return;
}
MID_Lock lock(p_dvector.mem);
int * rc = (int*)lock.data();
(*rc)++;
lock = MID_Lock();
mem=p_dvector.mem;
if (dvector_lock)
dvector_lock->unlock();
}
void unreference() {
if (dvector_lock)
dvector_lock->lock();
if (!mem.is_valid()) {
if (dvector_lock)
dvector_lock->unlock();
return;
}
MID_Lock lock(mem);
int * rc = (int*)lock.data();
(*rc)--;
if (*rc==0) {
// no one else using it, destruct
T * t= (T*)(rc+1);
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
for (int i=0;i<count;i++) {
t[i].~T();
}
}
lock = MID_Lock();
mem = MID ();
if (dvector_lock)
dvector_lock->unlock();
}
public:
class Read {
friend class DVector;
MID_Lock lock;
const T * mem;
public:
_FORCE_INLINE_ const T& operator[](int p_index) const { return mem[p_index]; }
_FORCE_INLINE_ const T *ptr() const { return mem; }
Read() { mem=NULL; }
};
class Write {
friend class DVector;
MID_Lock lock;
T * mem;
public:
_FORCE_INLINE_ T& operator[](int p_index) { return mem[p_index]; }
_FORCE_INLINE_ T *ptr() { return mem; }
Write() { mem=NULL; }
};
Read read() const {
Read r;
if (mem.is_valid()) {
r.lock = MID_Lock( mem );
r.mem = (const T*)((int*)r.lock.data()+1);
}
return r;
}
Write write() {
Write w;
if (mem.is_valid()) {
copy_on_write();
w.lock = MID_Lock( mem );
w.mem = (T*)((int*)w.lock.data()+1);
}
return w;
}
template<class MC>
void fill_with(const MC& p_mc) {
int c=p_mc.size();
resize(c);
Write w=write();
int idx=0;
for(const typename MC::Element *E=p_mc.front();E;E=E->next()) {
w[idx++]=E->get();
}
}
void remove(int p_index) {
int s = size();
ERR_FAIL_INDEX(p_index, s);
Write w = write();
for (int i=p_index; i<s-1; i++) {
w[i]=w[i+1];
};
w = Write();
resize(s-1);
}
inline int size() const;
T get(int p_index) const;
void set(int p_index, const T& p_val);
void push_back(const T& p_val);
void append(const T& p_val) { push_back(p_val); }
void append_array(const DVector<T>& p_arr) {
int ds = p_arr.size();
if (ds==0)
return;
int bs = size();
resize( bs + ds);
Write w = write();
Read r = p_arr.read();
for(int i=0;i<ds;i++)
w[bs+i]=r[i];
}
Error insert(int p_pos,const T& p_val) {
int s=size();
ERR_FAIL_INDEX_V(p_pos,s+1,ERR_INVALID_PARAMETER);
resize(s+1);
{
Write w = write();
for (int i=s;i>p_pos;i--)
w[i]=w[i-1];
w[p_pos]=p_val;
}
return OK;
}
bool is_locked() const { return mem.is_locked(); }
inline const T operator[](int p_index) const;
Error resize(int p_size);
void operator=(const DVector& p_dvector) { reference(p_dvector); }
DVector() {}
DVector(const DVector& p_dvector) { reference(p_dvector); }
~DVector() { unreference(); }
};
template<class T>
int DVector<T>::size() const {
return mem.is_valid() ? ((mem.get_size() - sizeof(int)) / sizeof(T) ) : 0;
}
template<class T>
T DVector<T>::get(int p_index) const {
return operator[](p_index);
}
template<class T>
void DVector<T>::set(int p_index, const T& p_val) {
if (p_index<0 || p_index>=size()) {
ERR_FAIL_COND(p_index<0 || p_index>=size());
}
Write w = write();
w[p_index]=p_val;
}
template<class T>
void DVector<T>::push_back(const T& p_val) {
resize( size() + 1 );
set( size() -1, p_val );
}
template<class T>
const T DVector<T>::operator[](int p_index) const {
if (p_index<0 || p_index>=size()) {
T& aux=*((T*)0); //nullreturn
ERR_FAIL_COND_V(p_index<0 || p_index>=size(),aux);
}
Read r = read();
return r[p_index];
}
template<class T>
Error DVector<T>::resize(int p_size) {
if (dvector_lock)
dvector_lock->lock();
bool same = p_size==size();
if (dvector_lock)
dvector_lock->unlock();
// no further locking is necesary because we are supposed to own the only copy of this (using copy on write)
if (same)
return OK;
if (p_size == 0 ) {
unreference();
return OK;
}
copy_on_write(); // make it unique
ERR_FAIL_COND_V( mem.is_locked(), ERR_LOCKED ); // if after copy on write, memory is locked, fail.
if (p_size > size() ) {
int oldsize=size();
MID_Lock lock;
if (oldsize==0) {
mem = dynalloc( p_size * sizeof(T) + sizeof(int) );
lock=MID_Lock(mem);
int *rc = ((int*)lock.data());
*rc=1;
} else {
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // out of memory
}
lock=MID_Lock(mem);
}
T *t = (T*)((int*)lock.data() + 1);
for (int i=oldsize;i<p_size;i++) {
memnew_placement(&t[i], T );
}
lock = MID_Lock(); // clear
} else {
int oldsize=size();
MID_Lock lock(mem);
T *t = (T*)((int*)lock.data() + 1);
for (int i=p_size;i<oldsize;i++) {
t[i].~T();
}
lock = MID_Lock(); // clear
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error
}
}
return OK;
}
#endif

View File

@ -1,248 +0,0 @@
/*************************************************************************/
/* engine.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 "engine.h"
#include "core/authors.gen.h"
#include "core/donors.gen.h"
#include "core/license.gen.h"
#include "core/version.h"
#include "core/version_hash.gen.h"
void Engine::set_iterations_per_second(int p_ips) {
ERR_FAIL_COND_MSG(p_ips <= 0, "Engine iterations per second must be greater than 0.");
ips = p_ips;
}
int Engine::get_iterations_per_second() const {
return ips;
}
void Engine::set_physics_jitter_fix(float p_threshold) {
if (p_threshold < 0)
p_threshold = 0;
physics_jitter_fix = p_threshold;
}
float Engine::get_physics_jitter_fix() const {
return physics_jitter_fix;
}
void Engine::set_target_fps(int p_fps) {
_target_fps = p_fps > 0 ? p_fps : 0;
}
int Engine::get_target_fps() const {
return _target_fps;
}
uint64_t Engine::get_frames_drawn() {
return frames_drawn;
}
void Engine::set_frame_delay(uint32_t p_msec) {
_frame_delay = p_msec;
}
uint32_t Engine::get_frame_delay() const {
return _frame_delay;
}
void Engine::set_time_scale(float p_scale) {
_time_scale = p_scale;
}
float Engine::get_time_scale() const {
return _time_scale;
}
Dictionary Engine::get_version_info() const {
Dictionary dict;
dict["major"] = VERSION_MAJOR;
dict["minor"] = VERSION_MINOR;
dict["patch"] = VERSION_PATCH;
dict["hex"] = VERSION_HEX;
dict["status"] = VERSION_STATUS;
dict["build"] = VERSION_BUILD;
dict["year"] = VERSION_YEAR;
String hash = VERSION_HASH;
dict["hash"] = hash.length() == 0 ? String("unknown") : hash;
String stringver = String(dict["major"]) + "." + String(dict["minor"]);
if ((int)dict["patch"] != 0)
stringver += "." + String(dict["patch"]);
stringver += "-" + String(dict["status"]) + " (" + String(dict["build"]) + ")";
dict["string"] = stringver;
return dict;
}
static Array array_from_info(const char *const *info_list) {
Array arr;
for (int i = 0; info_list[i] != NULL; i++) {
arr.push_back(info_list[i]);
}
return arr;
}
static Array array_from_info_count(const char *const *info_list, int info_count) {
Array arr;
for (int i = 0; i < info_count; i++) {
arr.push_back(info_list[i]);
}
return arr;
}
Dictionary Engine::get_author_info() const {
Dictionary dict;
dict["lead_developers"] = array_from_info(AUTHORS_LEAD_DEVELOPERS);
dict["project_managers"] = array_from_info(AUTHORS_PROJECT_MANAGERS);
dict["founders"] = array_from_info(AUTHORS_FOUNDERS);
dict["developers"] = array_from_info(AUTHORS_DEVELOPERS);
return dict;
}
Array Engine::get_copyright_info() const {
Array components;
for (int component_index = 0; component_index < COPYRIGHT_INFO_COUNT; component_index++) {
const ComponentCopyright &cp_info = COPYRIGHT_INFO[component_index];
Dictionary component_dict;
component_dict["name"] = cp_info.name;
Array parts;
for (int i = 0; i < cp_info.part_count; i++) {
const ComponentCopyrightPart &cp_part = cp_info.parts[i];
Dictionary part_dict;
part_dict["files"] = array_from_info_count(cp_part.files, cp_part.file_count);
part_dict["copyright"] = array_from_info_count(cp_part.copyright_statements, cp_part.copyright_count);
part_dict["license"] = cp_part.license;
parts.push_back(part_dict);
}
component_dict["parts"] = parts;
components.push_back(component_dict);
}
return components;
}
Dictionary Engine::get_donor_info() const {
Dictionary donors;
donors["platinum_sponsors"] = array_from_info(DONORS_SPONSOR_PLATINUM);
donors["gold_sponsors"] = array_from_info(DONORS_SPONSOR_GOLD);
donors["silver_sponsors"] = array_from_info(DONORS_SPONSOR_SILVER);
donors["bronze_sponsors"] = array_from_info(DONORS_SPONSOR_BRONZE);
donors["mini_sponsors"] = array_from_info(DONORS_SPONSOR_MINI);
donors["gold_donors"] = array_from_info(DONORS_GOLD);
donors["silver_donors"] = array_from_info(DONORS_SILVER);
donors["bronze_donors"] = array_from_info(DONORS_BRONZE);
return donors;
}
Dictionary Engine::get_license_info() const {
Dictionary licenses;
for (int i = 0; i < LICENSE_COUNT; i++) {
licenses[LICENSE_NAMES[i]] = LICENSE_BODIES[i];
}
return licenses;
}
String Engine::get_license_text() const {
return String(GODOT_LICENSE_TEXT);
}
void Engine::add_singleton(const Singleton &p_singleton) {
singletons.push_back(p_singleton);
singleton_ptrs[p_singleton.name] = p_singleton.ptr;
}
Object *Engine::get_singleton_object(const String &p_name) const {
const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name);
ERR_FAIL_COND_V_MSG(!E, NULL, "Failed to retrieve non-existent singleton '" + p_name + "'.");
return E->get();
};
bool Engine::has_singleton(const String &p_name) const {
return singleton_ptrs.has(p_name);
};
void Engine::get_singletons(List<Singleton> *p_singletons) {
for (List<Singleton>::Element *E = singletons.front(); E; E = E->next())
p_singletons->push_back(E->get());
}
Engine *Engine::singleton = NULL;
Engine *Engine::get_singleton() {
return singleton;
}
Engine::Engine() {
singleton = this;
frames_drawn = 0;
ips = 60;
physics_jitter_fix = 0.5;
_physics_interpolation_fraction = 0.0f;
_frame_delay = 0;
_fps = 1;
_target_fps = 0;
_time_scale = 1.0;
_gpu_pixel_snap = false;
_physics_frames = 0;
_idle_frames = 0;
_in_physics = false;
_frame_ticks = 0;
_frame_step = 0;
editor_hint = false;
}
Engine::Singleton::Singleton(const StringName &p_name, Object *p_ptr) :
name(p_name),
ptr(p_ptr) {
#ifdef DEBUG_ENABLED
Reference *ref = Object::cast_to<Reference>(p_ptr);
if (ref && !ref->is_referenced()) {
WARN_PRINT("You must use Ref<> to ensure the lifetime of a Reference object intended to be used as a singleton.");
}
#endif
}

View File

@ -1,130 +0,0 @@
/*************************************************************************/
/* engine.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 ENGINE_H
#define ENGINE_H
#include "core/list.h"
#include "core/os/main_loop.h"
#include "core/ustring.h"
#include "core/vector.h"
class Engine {
public:
struct Singleton {
StringName name;
Object *ptr;
Singleton(const StringName &p_name = StringName(), Object *p_ptr = NULL);
};
private:
friend class Main;
uint64_t frames_drawn;
uint32_t _frame_delay;
uint64_t _frame_ticks;
float _frame_step;
int ips;
float physics_jitter_fix;
float _fps;
int _target_fps;
float _time_scale;
bool _gpu_pixel_snap;
uint64_t _physics_frames;
float _physics_interpolation_fraction;
uint64_t _idle_frames;
bool _in_physics;
List<Singleton> singletons;
Map<StringName, Object *> singleton_ptrs;
bool editor_hint;
static Engine *singleton;
public:
static Engine *get_singleton();
virtual void set_iterations_per_second(int p_ips);
virtual int get_iterations_per_second() const;
void set_physics_jitter_fix(float p_threshold);
float get_physics_jitter_fix() const;
virtual void set_target_fps(int p_fps);
virtual int get_target_fps() const;
virtual float get_frames_per_second() const { return _fps; }
uint64_t get_frames_drawn();
uint64_t get_physics_frames() const { return _physics_frames; }
uint64_t get_idle_frames() const { return _idle_frames; }
bool is_in_physics_frame() const { return _in_physics; }
uint64_t get_idle_frame_ticks() const { return _frame_ticks; }
float get_idle_frame_step() const { return _frame_step; }
float get_physics_interpolation_fraction() const { return _physics_interpolation_fraction; }
void set_time_scale(float p_scale);
float get_time_scale() const;
void set_frame_delay(uint32_t p_msec);
uint32_t get_frame_delay() const;
void add_singleton(const Singleton &p_singleton);
void get_singletons(List<Singleton> *p_singletons);
bool has_singleton(const String &p_name) const;
Object *get_singleton_object(const String &p_name) const;
_FORCE_INLINE_ bool get_use_gpu_pixel_snap() const { return _gpu_pixel_snap; }
#ifdef TOOLS_ENABLED
_FORCE_INLINE_ void set_editor_hint(bool p_enabled) { editor_hint = p_enabled; }
_FORCE_INLINE_ bool is_editor_hint() const { return editor_hint; }
#else
_FORCE_INLINE_ void set_editor_hint(bool p_enabled) {}
_FORCE_INLINE_ bool is_editor_hint() const { return false; }
#endif
Dictionary get_version_info() const;
Dictionary get_author_info() const;
Array get_copyright_info() const;
Dictionary get_donor_info() const;
Dictionary get_license_info() const;
String get_license_text() const;
Engine();
virtual ~Engine() {}
};
#endif // ENGINE_H

View File

@ -3,10 +3,9 @@
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@ -27,7 +26,6 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef ERROR_LIST_H
#define ERROR_LIST_H
@ -39,55 +37,59 @@
*/
enum Error {
OK, // (0)
OK,
FAILED, ///< Generic fail error
ERR_UNAVAILABLE, ///< What is requested is unsupported/unavailable
ERR_UNCONFIGURED, ///< The object being used hasn't been properly set up yet
ERR_UNCONFIGURED, ///< The object being used hasnt been properly set up yet
ERR_UNAUTHORIZED, ///< Missing credentials for requested resource
ERR_PARAMETER_RANGE_ERROR, ///< Parameter given out of range (5)
ERR_OUT_OF_MEMORY, ///< Out of memory
ERR_FILE_NOT_FOUND,
ERR_FILE_BAD_DRIVE,
ERR_FILE_BAD_PATH,
ERR_FILE_NO_PERMISSION, // (10)
ERR_FILE_NO_PERMISSION, // (10)
ERR_FILE_ALREADY_IN_USE,
ERR_FILE_CANT_OPEN,
ERR_FILE_CANT_WRITE,
ERR_FILE_CANT_READ,
ERR_FILE_UNRECOGNIZED, // (15)
ERR_FILE_CORRUPT,
ERR_FILE_MISSING_DEPENDENCIES,
ERR_FILE_EOF,
ERR_CANT_OPEN, ///< Can't open a resource/socket/file
ERR_CANT_CREATE, // (20)
ERR_QUERY_FAILED,
ERR_CANT_CREATE,
ERROR_QUERY_FAILED, // (20)
ERR_ALREADY_IN_USE,
ERR_LOCKED, ///< resource is locked
ERR_TIMEOUT,
ERR_CANT_CONNECT, // (25)
ERR_CANT_RESOLVE,
ERR_LOCKED, ///< resource is locked
ERR_TIMEOUT,
ERR_CANT_CONNECT,
ERR_CANT_RESOLVE, // (25)
ERR_CONNECTION_ERROR,
ERR_CANT_ACQUIRE_RESOURCE,
ERR_CANT_AQUIRE_RESOURCE,
ERR_CANT_FORK,
ERR_INVALID_DATA, ///< Data passed is invalid (30)
ERR_INVALID_PARAMETER, ///< Parameter passed is invalid
ERR_INVALID_DATA, ///< Data passed is invalid
ERR_INVALID_PARAMETER, ///< Parameter passed is invalid (30)
ERR_ALREADY_EXISTS, ///< When adding, item already exists
ERR_DOES_NOT_EXIST, ///< When retrieving/erasing, if item does not exist
ERR_DOES_NOT_EXIST, ///< When retrieving/erasing, it item does not exist
ERR_DATABASE_CANT_READ, ///< database is full
ERR_DATABASE_CANT_WRITE, ///< database is full (35)
ERR_COMPILATION_FAILED,
ERR_METHOD_NOT_FOUND,
ERR_LINK_FAILED,
ERR_DATABASE_CANT_WRITE, ///< database is full
ERR_COMPILATION_FAILED, // (35)
ERR_METHOD_NOT_FOUND,
ERR_LINK_FAILED,
ERR_SCRIPT_FAILED,
ERR_CYCLIC_LINK, // (40)
ERR_INVALID_DECLARATION,
ERR_CYCLIC_LINK,
ERR_INVALID_DECLARATION, // (40)
ERR_DUPLICATE_SYMBOL,
ERR_PARSE_ERROR,
ERR_BUSY,
ERR_SKIP, // (45)
ERR_HELP, ///< user requested help!!
ERR_SKIP,
ERR_HELP, ///< user requested help!! (45)
ERR_BUG, ///< a bug in the software certainly happened, due to a double check failing or unexpected behavior.
ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames
ERR_OMFG_THIS_IS_VERY_VERY_BAD, ///< shit happens, has never been used, though
ERR_WTF = ERR_OMFG_THIS_IS_VERY_VERY_BAD ///< short version of the above
};
#endif

Some files were not shown because too many files have changed in this diff Show More