Compare commits

...

699 Commits

Author SHA1 Message Date
Rémi Verschelde
d8ae244d51 Revert "Respect style boxes for Button states other than "normal""
This reverts commit 98f01f9143.
This made icons in the editor "jumpy" on hover.
2017-04-11 19:45:39 +02:00
Rémi Verschelde
8df5b7151f Release 2.1.3-stable 2017-04-10 23:44:55 +02:00
Rémi Verschelde
3b687c5474 Move VERSION_MKSTRING logic to version.h
Fixes a bug where the VERSION_PATCH define is not yet in scope if
typedefs.h is included before version.h at compilation time.
2017-04-10 23:08:28 +02:00
Rémi Verschelde
c449df86f7 Mark Godot 3.0 exporter as work in progress 2017-04-10 19:40:08 +02:00
Rémi Verschelde
45bf6d9f20 .gitignore: Add app_icon.h and splash.h generated headers
Also sort alphabetically for clarity.
2017-04-10 18:36:31 +02:00
Andreas Haas
37d9a7bee4 Re-add ouya gamepad mapping.
Also adds yet another type of ps4 controller.
2017-04-10 16:38:44 +02:00
Rémi Verschelde
2515ff5577 Merge pull request #8327 from akien-mga/2.1-godot3-exporter
Godot3 exporter: Convert engine.cfg properly
2017-04-09 17:46:56 +02:00
Rémi Verschelde
b46d7f986d Merge pull request #8320 from RandomShaper/zero-preprocess-particles2d-2.1
Allow a preprocess time of 0 for Particles2D (2.1)
2017-04-09 17:44:23 +02:00
Rémi Verschelde
b7e3ef5f6f libpng: Update to upstream version 1.6.29
(cherry picked from commit d463b6e3d0)
2017-04-09 15:52:14 +02:00
Rémi Verschelde
2bc0208b2c opus: Update to upstream version 1.1.4
(cherry picked from commit dd8655aac9)
2017-04-09 15:51:48 +02:00
Rémi Verschelde
20d1a28341 squish: Update to upstream version 1.15
Also fix clang-format pre-commit hook to ignore thirdparty files.

(cherry picked from commit fa2d5b91dc)
2017-04-09 15:51:41 +02:00
Rémi Verschelde
a27876d5ac Style: Apply clang-format (3.9.1) to Obj-C++ files 2017-04-09 14:03:52 +02:00
Rémi Verschelde
a7a5ac596e Godot3 exporter: Convert engine.cfg properly
Use a map to keep track of renamings as done for other properties.
The saving is a bit hackish, there might be simpler solutions.
2017-04-09 02:11:36 +02:00
Rémi Verschelde
fb4e9962ea Merge pull request #8326 from Hinsbart/particle_flip
Particles2D: Fix flip property (again).
2017-04-09 01:21:19 +02:00
Andreas Haas
9b6b713d61 Particles2D: Fix flip property (again).
should have flipped the dst_rect..
2017-04-09 01:16:48 +02:00
Rémi Verschelde
c9eb0f5f45 Merge pull request #8317 from RandomShaper/fix-area-monitoring-2.1
Fix side effects of the bookkepping of Area/Area2D's monitoring (2.1)
2017-04-08 22:47:44 +02:00
Pedro J. Estébanez
86966940ff Allow a preprocess time of 0 for Particles2D 2017-04-08 20:00:24 +02:00
Rémi Verschelde
4b561e3e04 Merge pull request #8311 from BastiaanOlij/format_mm_2.1
Spaces to tabs and layout adjustments on .mm files
2017-04-08 16:49:51 +02:00
Rémi Verschelde
f90eb87193 Revert "Make inline blocks in GDScript more pythonic"
This reverts commit 0c650c2511.
Fixes #8315.
2017-04-08 16:08:22 +02:00
Pedro J. Estébanez
c3c0cfd207 Fix side effects of the bookkepping of Area/Area2D's monitoring
- Fix monitoring flag being reset when the scene is out of the tree (happens on save all if the current scene is not the focused one, therefore on save-on-run as well)
- Fix the inability to reset the monitoring flag while the area is out of the tree
2017-04-08 13:24:29 +02:00
Rémi Verschelde
7f32db5ac9 Revert "8145 - Mouse Position is unknown until first mouse event on X11 & Win"
This reverts commit e5d63aaece.
Same reasoning as #8291.
2017-04-08 11:28:25 +02:00
BastiaanOlij
33ea9fc4a7 Spaces to tabs and layout adjustments on .mm files 2017-04-08 09:47:13 +10:00
Rémi Verschelde
2491754de7 Style: Fix some badly formatted files 2017-04-08 01:42:41 +02:00
Rémi Verschelde
e9b045d9e5 Add "Godot Engine contributors" copyright line 2017-04-08 00:45:24 +02:00
Rémi Verschelde
b55b66d74e Add AUTHORS list crediting developers
(cherry picked from commit 21bcb71b2c)
2017-04-08 00:41:40 +02:00
Rémi Verschelde
63ddee793e Merge pull request #8307 from RandomShaper/optimize-out-debug-n-non-tools-2.1
Optimize-out some debug and/or non-tools methods (2.1)
2017-04-07 22:22:43 +02:00
Rémi Verschelde
6f489fbb2e classref: Sync with current source 2017-04-07 22:08:11 +02:00
Rémi Verschelde
64d8eeb4a1 i18n: Sync translations with Weblate 2017-04-07 21:26:46 +02:00
Rémi Verschelde
6d722f2622 i18n: Add WIP Czech, Danish, Greek, Dutch and Thai translations 2017-04-07 21:25:56 +02:00
Rémi Verschelde
593149b1a0 i18n: Update template with current source 2017-04-07 21:22:11 +02:00
Rémi Verschelde
990e8e00c7 Merge pull request #8303 from RandomShaper/reset-folded-on-reset-edit-children-2.1
Reset display folded for an instanced scene if editable children is toggled off (2.1)
2017-04-07 19:10:03 +02:00
Pedro J. Estébanez
1b15c53479 Optimize-out some debug and/or non-tools methods
Collisions and nav debug are conditionally compiled depending on DEBUG_ENABLED
is_editor_hint() and is_node_being_edited() are compiled only with TOOLS_ENABLED
Every affected method is implemented in the header in case its macro is not present (the getters just returning false and the setters having an empty body) so the compiler can inline and finally no-op-out them as likely as possible.
is_node_being_edited() already showed a similar optimization effort and has been adapted to this change.
Furthermore, and as a consequence, -debugcol and -debugnav will not work on non-debug (strict release) builds.
This can bring a little bit of runtime performance on release and non-tooled builds (less code, so less cycles to spend and maybe more cache friendly).
2017-04-07 16:34:15 +02:00
Pedro J. Estébanez
4087e61900 Reset display folded for an instanced scene if editable children is toggled off
This avoids the display folded flag needlessly getting into the scene file (potentially forever) and also gives more visual feedback if the user re-enables editable children so it will display unfolded at first.
2017-04-07 15:46:13 +02:00
Rémi Verschelde
2ee9e033ec Merge pull request #8202 from williamd1k0/add-script-button
Add Attach and Clear Script buttons (2.1)
2017-04-07 08:54:39 +02:00
Rémi Verschelde
f7c3ecb38c Merge pull request #8294 from RandomShaper/sample-players-priority-2.1
Add priority to samples in a library (2.1)
2017-04-07 08:06:51 +02:00
Pedro J. Estébanez
9f8f8efa67 Add priority to samples in a library 2017-04-06 23:59:49 +02:00
Rémi Verschelde
3916d964de Merge pull request #8293 from Faless/2.1-enum
[2.1] Cherry pick GDScript enum support ( #6292 )
2017-04-06 23:05:29 +02:00
Rémi Verschelde
6ff1436fde Merge pull request #8292 from RandomShaper/spatial-audio-play-on-free-2.1
Make spatial AudioServers prefer inactive voices (2.1)
2017-04-06 23:05:06 +02:00
Pedro J. Estébanez
0501f3a901 Make spatial AudioServers prefer inactive voices
instead of unconditionally playing on the next voice slot; that will be the fallback if no inactive voice is found
2017-04-06 20:11:26 +02:00
Bojidar Marinov
dad8e04139 Add enum naming, by assinging a given enum's values to a Dict
(cherry picked from commit 88430f0962)
2017-04-06 19:01:43 +02:00
Bojidar Marinov
ed80f4563a Adds enums to GDScript
Fixes #2966

(cherry picked from commit 4ee82a2c38)
2017-04-06 19:01:43 +02:00
Rémi Verschelde
f71da5c8c5 Merge pull request #8273 from RandomShaper/fix-android-x86-2.1
Fix crash on Android-x86 (2.1)
2017-04-05 22:27:58 +02:00
Pedro J. Estébanez
212fca0c50 Fix crash on Android-x86 2017-04-05 22:16:04 +02:00
Rémi Verschelde
9a9bd12913 Fixer looping timer accumulation in _process
Follow-up to #8251.

(cherry picked from commit 5b5a825c7f)
2017-04-05 08:24:15 +02:00
Nikhil Shagrithaya
323041a476 previous value of time_left is added to wait_time before assigning to time_left
(cherry picked from commit ea4fbee8f2)
2017-04-05 08:23:34 +02:00
volzhs
a67400aee7 Make buttons closer in Scene tree
(cherry picked from commit a911b1f126)
2017-04-05 08:19:57 +02:00
Andreas Haas
1620f46f03 Viewport: Fix undefined behaviour found by llvm sanitizer.
When godot was running as the project manager, it tried to call a method on a null pointer (get_tree()->get_edited_scene_root()).
This is undefined behaviour and caused a crash when compiled with sanitizing enabled.

(cherry picked from commit 1d3c9c448d)
2017-04-05 08:18:59 +02:00
Fabian Mathews
1a1e25bfca Added ability to change A-star cost function
(cherry picked from commit b541402417)
2017-04-05 08:18:38 +02:00
Saggi Mizrahi
89b201b466 Add the option to check if input was handled
When working with a viewport you should call Viewport.input() to pass
the input, but if the input was unhandled you might also want to call
Viewport.unhandled_input() so that objects in the sub-scene can handle
the event. This adds a way to check if the input was handled so that you
know whether you should call Viewport.unhandled_input() or not.

Signed-off-by: Saggi Mizrahi <saggi@mizrahi.cc>
(cherry picked from commit 245ace6e2e)
2017-04-05 08:15:15 +02:00
Sergey Pusnei
e5d63aaece 8145 - Mouse Position is unknown until first mouse event on X11 & Win
- X11 update input->pos on EnterNotify
- X11 & Win call first-time events processing before main initialization

(cherry picked from commit c79e998d1f)
2017-04-05 08:08:08 +02:00
Ramesh Ravone
1c17e5b38d Update build.gradle.template
Updating project repository,
added jcenter() since Android Studio uses it by default.

https://www.jfrog.com/knowledge-base/why-should-i-use-jcenter-over-maven-central/
(cherry picked from commit 77c81a21d8)
2017-04-05 08:07:01 +02:00
Rémi Verschelde
e10e732bf0 Merge pull request #8242 from volzhs/area-monitoring
Fix monitoring status of Area2D and doing same logic on Area too
2017-04-04 23:04:20 +02:00
volzhs
6222821535 Apply same logic to Area with Area2D
comes from 5b556ca and 73f53a7
2017-04-04 10:37:45 +09:00
Rémi Verschelde
d047e67977 Merge pull request #8243 from RandomShaper/improve-touch-button-2.1
Improve TouchScreenButton (2.1)
2017-04-04 00:19:50 +02:00
Pedro J. Estébanez
7d642e218e Improve TouchScreenButton
Fix shape not being updated
Add a way to hide the shape on editor and debug-with-visible-shapes
Remove useless checks
2017-04-03 14:38:01 +02:00
volzhs
73f53a7918 Fix monitoring status of Area2D 2017-04-03 21:00:38 +09:00
Rémi Verschelde
12749dd67a Merge pull request #8240 from volzhs/crash-project-setting
Fix crash when change project settings
2017-04-03 11:34:14 +02:00
volzhs
ddd01332ef Fix crash when change project settings 2017-04-03 17:49:02 +09:00
Rémi Verschelde
d0b0a3241f Merge pull request #8236 from RandomShaper/fix-warped-pan-2.1
Fix warped mouse panning on Linux (2.1)
2017-04-03 07:57:32 +02:00
Pedro J. Estébanez
5889169bbd Fix warped mouse panning on Linux
Fix/improve it also on certain edge cases for any platform
2017-04-03 02:59:03 +02:00
Rémi Verschelde
603f83ba91 Merge pull request #8230 from Hinsbart/upd_mappings_2.1
Input: Update Gamepad mappings. [2.1]
2017-04-02 13:02:39 +02:00
Andreas Haas
33f9873b70 Input: Update Gamepad mappings. 2017-04-02 09:59:53 +02:00
Andreas Haas
6438823037 Merge pull request #8166 from evolarium/joystick_fix
Initialize hat values for mapping and revert X360 mappings.
2017-03-30 14:16:03 +02:00
Rémi Verschelde
6392381c16 Merge pull request #8204 from Shin-NiL/2.1
Honor the Tween's final values
2017-03-30 13:09:21 +02:00
Rémi Verschelde
fd5215bffb Merge pull request #8179 from efornara/2.1
Allow remote debugging on disconnected Windows machines
2017-03-30 10:30:59 +02:00
Rémi Verschelde
2798a85ba7 Merge pull request #8172 from RandomShaper/improve-tile-palette-2.1
Several enhancements for the tile map editor (2.1)
2017-03-30 10:29:53 +02:00
Shin-NiL
ca96d7940e Honor the Tween's final values 2017-03-29 19:35:51 -03:00
William Tumeo
d90809151f Re-add attach button and context menu from 1880238c3e 2017-03-29 18:36:58 -03:00
William Tumeo
1307ff7eb1 Re-add clear script button and context menu from ce5200b30e 2017-03-29 17:23:49 -03:00
Emanuele Fornara
facacb886c Workaround to allow debugging on Windows when offline 2017-03-29 19:44:18 +01:00
William Tumeo
5d8d51719a Re-add script icons from 544194053a 2017-03-29 04:06:53 -03:00
William Tumeo
95f747ec93 Re-add create/load script button and context menu
- create from f51b202566
- load from 41329f9750
2017-03-29 03:46:35 -03:00
William Tumeo
225b1d2d76 Re-add script button from b77200728e 2017-03-29 02:16:26 -03:00
Jordan Patterson
391f6c5536 Initialize hat values for mapping and revert X360 mappings. 2017-03-27 11:00:37 -06:00
Pedro J. Estébanez
bba31fbad7 Several enhancements for the tile map editor
Allow sorting tile palette by name
Allow hiding tile ids in tile palette
2017-03-27 10:46:44 +02:00
Rémi Verschelde
e3d6d863af Merge pull request #8170 from RandomShaper/fix-uniform-move-2.1
Include uniform (Shift down) mode in only-one-Node2D dragging (2.1)
2017-03-27 08:57:05 +02:00
Rémi Verschelde
b3d1113ae3 Merge pull request #8152 from Hinsbart/input_id_2.1
[2.1] Better handling of joypad device IDs.
2017-03-27 08:51:15 +02:00
Rémi Verschelde
93107f4245 Merge pull request #8141 from elasota/fix-unshaded-spillover
Fix renderer sometimes not applying "unshaded" flag (2.1)
2017-03-27 08:47:15 +02:00
Pedro J. Estébanez
3bdb29b077 Include uniform (Shift down) mode in only-one-Node2D dragging 2017-03-27 01:32:16 +02:00
Rémi Verschelde
62d8f96720 Remove redundant subfolder in iOS template
(cherry picked from commit 1a0d1bb18d)
2017-03-26 22:04:29 +02:00
Rémi Verschelde
d3e6f58c25 Merge pull request #8142 from akien-mga/2.1-warnings-option
SCons: Add option to toggle warnings (on by default)
2017-03-26 21:54:30 +02:00
Andreas Haas
8c06da0d49 Better handling of joypad device IDs.
Now InputDefault is responsible for giving out joypad device IDs to the platform, instead of each platform handling this itself.
This makes it possible for c++ modules to add their own "custom" gamepad devices, without the risk of messing up events in case the user also has regular gamepads attached (using the OS code).
For now, it's implemented for the main desktop platforms.
Possible targets for future work: android, uwp, javascript
2017-03-26 00:12:11 +01:00
Rémi Verschelde
31107daa1a SCons: Add option to toggle warnings (on by default)
All the warnings are factored out of the platform-specific files and moved to
SConstruct. Will have to check that it does not introduce regressions on some
platforms/compilers.
2017-03-25 09:24:29 +01:00
elasota
5d691350c4 Fixed "unshaded" flag not being updated if light_type and receive_shadows_state didn't change. 2017-03-24 20:27:06 -04:00
Andreas Haas
ed3134088b Input: Update mouse position on mouse-button events.
(cherry picked from commit 468719c480)
2017-03-24 23:19:49 +01:00
Ferenc Arn
f263274a25 Use atan2 rather than acos in Vector3.angle_to.
Fixes #8111.

(cherry picked from commit 3730e0533c)
2017-03-24 23:19:30 +01:00
Bojidar Marinov
0c650c2511 Make inline blocks in GDScript more pythonic
Fixes #8001

(cherry picked from commit 18ab88b3f1)
2017-03-24 23:19:14 +01:00
Bojidar Marinov
0afb9b579f Suppress error messages when using ConfigFile::get_value and a default is given
Fixes #8097

(cherry picked from commit 927d15b815)
2017-03-24 23:17:08 +01:00
Rémi Verschelde
8f5b15754c Merge pull request #8114 from RandomShaper/improve-snapping-2.1
Improved 2D snapping behavior (2.1)
2017-03-24 22:51:09 +01:00
Rémi Verschelde
a9d63bcf6f Merge pull request #8107 from RandomShaper/warped-panning-2.1
Implement warped mouse panning for 2D & 3D editors (2.1)
2017-03-24 22:50:34 +01:00
Rémi Verschelde
2c95976ef7 Merge pull request #8099 from RandomShaper/close-output-2.1
Add editor option for automatically closing the output when stopping the game (2.1)
2017-03-24 22:50:02 +01:00
Rémi Verschelde
492f6e06c0 Merge pull request #8088 from BastiaanOlij/android_gravity_2.1
Android gravity vector Godot 2.1
2017-03-24 22:49:23 +01:00
Rémi Verschelde
15b6eadba7 i18n: Sync templates and translations with current code 2017-03-24 22:27:22 +01:00
Rémi Verschelde
d2e8a21cb1 i18n: Adapt script to tools/editor -> editor move 2017-03-24 22:24:56 +01:00
Pedro J. Estébanez
adf36faee8 Improved 2D snapping behavior
Make snapping affect nodes created by drag & drop
Make snapping for a single Node2D refer to its pivot
Refactor duplicate drag setup code
2017-03-24 21:27:37 +01:00
Rémi Verschelde
a531051a61 Only assume HiDPI mode if DPI >= 192 and width > 2000
Also use single-dock column if width < 1200.

Manually adapted from bfe67a3b87
and c103f32ea3.

Fixes #6096.
2017-03-24 18:26:56 +01:00
Rémi Verschelde
fd17d301d0 Merge pull request #8100 from BastiaanOlij/ios_magnetometer_2.1
Fixing magnetometer on iOS
2017-03-23 09:57:29 +01:00
Rémi Verschelde
aaf4e3ab9f Merge pull request #8108 from Faless/2.1-v6fix-cherry
Cherry pick #7510 and #7581 to 2.1
2017-03-23 08:29:08 +01:00
Pedro J. Estébanez
2c2c48ffb3 Implement warped mouse panning for 2D & 3D editors
Enabled by default as in Blender, but can be disabled separately for 2D & 3D;
the core functionality is in Input so this could be reused or even exposed to scripts in the future
2017-03-22 21:18:47 +01:00
Fabio Alessandrelli
15ecdb5f00 Fix buffer size check in UDP socket.
We were reserving 12 bytes from the buffer for ip, port, and length, but since
IPv6 introduction we should be reserving 24 (IPv6 are 16 bytes)

(cherry picked from commit 5dc7c920bf)
2017-03-22 21:11:49 +01:00
Fabio Alessandrelli
994df5df5c Use default UDP ring buffer size of 65536 for clients
We should probably create a specific function for setting the
recv buffer anyway. UDP sockets does not need to bind (listen)
to be able to call recvfrom. This is especially useful for clients
who just call set_send_address and start communicating with a server.

(cherry picked from commit 9336857132)
2017-03-22 21:07:27 +01:00
Fabio Alessandrelli
7dbccc9a57 Fix bug causing UDP socket to close after the first send if not listening
The ring buffer for receiving packets was not resized in constructor

(cherry picked from commit 68dc969f8c)
2017-03-22 21:05:27 +01:00
Fabio Alessandrelli
cab9ad7657 Update docs reference for TCP_Server::listen and UDPPacketPeer::listen
(cherry picked from commit e5e4e7b6a9)
2017-03-22 21:05:02 +01:00
Fabio Alessandrelli
9f41c0a356 Avoid deadlock when writing/reading data on a connecting TCP socket
TCP status polling is always performed as non blocking.
Trying to put a packet on a connecting socket will fail immediately.

(cherry picked from commit fa0cb7da0e)
2017-03-22 21:03:26 +01:00
Fabio Alessandrelli
86de0bd081 Bind to IPv4 on OpenBSD when using wildcard
OpenBSD does not support binding on both IPv4 and IPv6 using the same socket

(cherry picked from commit 619e7a2c8b)
2017-03-22 21:01:14 +01:00
Fabio Alessandrelli
d9525082fe Remove set_ip_type from network classes (no longer needed)
- TCP:
  - `listen` bind to wildcard "*" -> dual stack socket
  - `listen` bind to address -> socket from address type
  - `connect` -> resolve using best protocol (UNSPEC), socket from address type

- UDP:
  - `listen` bind to wildcard "*" -> dual stack socket
  - `listen` bind to address -> socket from address type
  - `put_packet`/`put_var` -> resolve using TYPE_ANY (UNSPEC), socket from address type
    (to change socket type you must first call `close` it)

(cherry picked from commit 88a56ba783)
2017-03-22 21:00:23 +01:00
Fabio Alessandrelli
0b9684a085 Implement UDP listen bind address
(cherry picked from commit 2fe4ef6699)
2017-03-22 20:25:56 +01:00
Fabio Alessandrelli
43d992fc34 Implement TCP Server bind address
(cherry picked from commit b2839343ca)
2017-03-22 20:25:52 +01:00
Fabio Alessandrelli
90a747a52d IP_Address can now be a wildcard (not a valid IP, used for binding)
(cherry picked from commit 4198291cd4)
2017-03-22 20:01:41 +01:00
Fabio Alessandrelli
603105df18 Convert validity checks of IP_Address to is_valid method.
(cherry picked from commit 98a7e2b4e0)
2017-03-22 20:01:41 +01:00
Fabio Alessandrelli
aeffe74a27 Avoid calling close when polling a UDP peer without socket
(cherry picked from commit e4b9b37ccf)
2017-03-22 20:01:13 +01:00
Fabio Alessandrelli
ccf37c4ca2 TCP connect always opens correct socket type
TCP client connections does not need to rely on ipv6 dual stack sockets

(cherry picked from commit 55b4f3686d)
2017-03-22 15:40:31 +01:00
BastiaanOlij
4b7d1d8c15 Fixing magnetometer on iOS 2017-03-21 23:50:53 +11:00
Pedro J. Estébanez
e1d18e6481 Add editor option for automatically closing the output when stopping the game
(back-ported from 1bd1af776c)
2017-03-21 12:47:05 +01:00
BastiaanOlij
cc6810c030 Android gravity vector Godot 2.1 2017-03-21 22:45:24 +11:00
Rémi Verschelde
a14ad02d15 Merge pull request #8094 from RandomShaper/fix-yield-crash-2.1
Fix random crashes when using yield() (2.1)
2017-03-21 11:07:34 +01:00
Pedro J. Estébanez
48da11372e Fix random crashes when using yield() 2017-03-21 02:54:46 +01:00
Rémi Verschelde
9c75b9dddf Merge pull request #8091 from RandomShaper/fix-particles-2d-2.1
Fix Particles2D process mode back-compat issue (2.1)
2017-03-20 19:49:58 +01:00
Pedro J. Estébanez
98ba3db502 Fix Particles2D process mode back-compat issue 2017-03-20 19:47:25 +01:00
Rémi Verschelde
ea987256f6 Revert "Fix drag and drop on 2d viewport"
This reverts commits a9d8da91b7
and 4230b22558.
2017-03-20 16:57:29 +01:00
Rémi Verschelde
51c5a12f43 Travis: Run clang-format static check
Commits or PRs that do not respect the clang-format style that we
enforce will fail the test.

Adding ubuntu-toolchain-r-test as its libstdc++ is necessary to install
libllvm-3.9.

(cherry picked from commit 6aee289b3e)
2017-03-19 16:14:53 +01:00
Rémi Verschelde
3251e93cee Fix linking order for builtin freetype
Before this change the libfreetype_builtin.a lib would be appended
at the very end of the linking flags, after system libs such as -lX11
or -lkernel32.

(cherry picked from commit 26c6c2b01a)
2017-03-19 16:14:47 +01:00
Rémi Verschelde
4230b22558 Fix cherry-pick mistake using 3.0 method
Bug introduced in a9d8da91b7.
2017-03-19 10:01:53 +01:00
Rémi Verschelde
f4f0a6c609 Merge pull request #8073 from Hinsbart/bind_parse_ev
Input: bind parse_input_event() [2.1]
2017-03-19 10:00:00 +01:00
Andreas Haas
2f1a0448a7 Input: bind parse_input_event()
When using get_tree().input_event(ev), the engine will JUST send the event down the SceneTree.
However, you won't get any of the benefits of the Input singleton:
- No InputMap actions will be emitted
- The internal input state won't be modified, so methods like `Input.get_mouse_pos()` or `Input.is_joy_button_pressed` won't return the expected output after sending the event.

This is fixed by using `Input.parse_input_event(ev)` instead.
I guess we'll also have to update the docs to reflect that this is the preferred method of sending custom InputEvents.
2017-03-19 08:33:07 +01:00
Andreas Haas
c5c546fb7f X11: Don't reset mouse cursor theme.
On KDE (and possibly others) the "default" cursor theme is actually some system default, not the one you've set in the desktop setting.
This was especially annoying when using a white cursor, as Godot would then reset back to a dark one.
In my case it was also keeping the cursor from changing its shape.

(cherry picked from commit fc84ccc468)
2017-03-19 00:44:22 +01:00
Ramesh Mani Maran
f2f2369db8 android: adding classpath and gradle plugins
(cherry picked from commit 27c7d253aa)
2017-03-19 00:44:13 +01:00
Andreas Haas
3c16e7842f Editor: Fix "About" dialog
Use a HBoxContainer instead of hardcoded positions.

(cherry picked from commit 7ec697695f)
2017-03-19 00:44:05 +01:00
mbalint12
82ad45024f Fixed typo in gdscript autocompletion.
There was a missing '!' sign, but autocompletion shows parent script members too.

(cherry picked from commit edaf77abd6)
2017-03-19 00:43:07 +01:00
denis
e3e86567ba Update mouse position on touch and release events (Android)
(cherry picked from commit 55835167a4)
2017-03-19 00:42:58 +01:00
CrazyGuy108
10119f7b04 List Control::has_point as a virtual method
According to Issue #8018, a BIND_VMETHOD macro wasn't present in scene/gui/control.cpp, while it was declared to be a virtual method in scene/gui/control.h.

classes.xml was updated to also list this method in Control.

(cherry picked from commit 9589936d6e)
2017-03-19 00:42:34 +01:00
volzhs
a9d8da91b7 Fix drag and drop on 2d viewport
(cherry picked from commit 4d0a75750f)
2017-03-19 00:40:54 +01:00
AlexHolly
cf7ba8e390 fix remove_and_skip()
(cherry picked from commit 3f78f1f17d)
2017-03-19 00:38:36 +01:00
Ignacio Etcheverry
94653f0e88 Fix connection errors when replacing node
- Avoid connecting the signals to nonexistent methods
- Preserve only persistent connections

(cherry picked from commit d210ac66ef)
2017-03-19 00:38:30 +01:00
Rémi Verschelde
f8db8a3faa Bring that Whole New World to the Old Continent too
Applies the clang-format style to the 2.1 branch as done for master in
5dbf1809c6.
2017-03-19 00:36:26 +01:00
Rémi Verschelde
1d418afe86 Prevent cyclical dependency issue after clang-format includes reorder 2017-03-19 00:33:35 +01:00
Rémi Verschelde
d4e0be7632 Add missing map.h include in color defs
(cherry picked from commit 5e13a762ec)
2017-03-19 00:32:58 +01:00
Rémi Verschelde
2664549916 Prevent MSVC build issue after clang-format includes reorder 2017-03-18 23:49:09 +01:00
Rémi Verschelde
1b0e2b0c39 Refactoring: rename tools/editor/ to editor/
The other subfolders of tools/ had already been moved to either
editor/, misc/ or thirdparty/, so the hiding the editor code that
deep was no longer meaningful.

(Manual redo of 49c065d29c)
2017-03-18 23:45:45 +01:00
Rémi Verschelde
9d2c0f6c6e clang-format: Add pre-commit hook
Derived from https://github.com/githubbrowser/Pre-commit-hooks
and https://gitlab.cern.ch/GeantV/geant/blob/master/hooks/pre-commit-clang-format

(cherry picked from commit 0e4ee5935a)
2017-03-18 23:29:45 +01:00
Rémi Verschelde
19f90b59d5 Style: Add .clang-format based on LLVM style
Adapted some parameters to fit the de facto Godot style as closely as possible
(tab indentation, long lines with no wrapping - for now -, indented case labels,
left-aligned pointer operators).

(cherry picked from commit 503c98ead4)
2017-03-18 23:29:45 +01:00
Rémi Verschelde
6e5246e312 Reorder the folders in tools to prepare moving tools/editor
- `certs` and `editor_fonts` go to `thirdparty`
- `dist` and `scripts` go to a new `misc` folder
- `collada` and `doc` go to `tools/editor`

The next step will be to rename `tools/editor` to `editor` directly,
but this will be done at the right time to avoid breaking too many PRs.

(cherry picked from commit b87a232668)
2017-03-18 23:29:43 +01:00
Rémi Verschelde
16b78da941 Style: Various fixes to play nice with clang-format
(cherry picked from commit 2a0ddc1e89)
2017-03-18 23:13:47 +01:00
Rémi Verschelde
2d479aa0c6 Style: Prevent clang-format on JS code
(cherry picked from commit 39114178a0)
2017-03-18 22:52:28 +01:00
Rémi Verschelde
dbf0137576 Style: Fix statements ending with ';;'
(cherry picked from commit f44ee891be)
2017-03-18 21:14:33 +01:00
Rémi Verschelde
75bf6a9978 Style: Keep long lines for now
clang-format does not play well with tab-aligned multiline statements...
Some more research will be needed if we want to set a column limit.

(cherry picked from commit e2a3f06f3d)
2017-03-18 21:06:07 +01:00
Rémi Verschelde
4bfecab813 Style: No break before list brace
clang-format does not handle that well *at all*.

For the reference, found the relevant pieces of code with:
`ag "=[ "$'\t'"]?"$'\n'"[ "$'\t'"]?{" --ignore=thirdparty`

(cherry picked from commit 40323407df)
2017-03-18 21:05:58 +01:00
Rémi Verschelde
9992509b0d iphone: Drop unused Appirater thirdparty API
(cherry picked from commit 481e511082)
2017-03-18 20:22:23 +01:00
Ramesh Mani Maran
9b26e9c9ac support for multiple maven url
(cherry picked from commit aa7490ffd0)
2017-03-18 20:21:49 +01:00
volzhs
5ac097a035 Fix wrong TreeItem reference after reconstructing
(cherry picked from commit 66b7586fb0)
2017-03-18 20:21:05 +01:00
Shlomi Fish
cb2cdce6b8 Fix failing build on mageia v6 x64 linux.
There was an error about undeclared malloc()+free().

(cherry picked from commit 0ef3d22d98)
2017-03-18 20:19:57 +01:00
volzhs
db6d9cdc22 Fix crash when click icon while editing node name
(cherry picked from commit 3ae0ffa182)
2017-03-18 20:17:13 +01:00
Andreas Haas
96e0fd5570 Tween: Fix undefined behavior found by static code analyzer.
Adresses the issue mentioned in https://software.intel.com/en-us/articles/the-ultimate-question-of-programming-refactoring-and-everything

(cherry picked from commit 0157969ccc)
2017-03-18 20:16:40 +01:00
Bojidar Marinov
ecb4d41d20 Add Rect2 TileMap::get_used_rect(), closes #4390
(cherry picked from commit 136e1e18ba)
2017-03-18 20:16:14 +01:00
Andreas Haas
7bf7fe854f Don't switch to script on breakpoint hit when using external editor.
Fixes #7705

(cherry picked from commit 10fa752ae7)
2017-03-18 20:13:59 +01:00
Ignacio Etcheverry
77cb8f058d Replace misuse of list iteration
(cherry picked from commit 0cd309c5c7)
2017-03-18 20:13:17 +01:00
Hein-Pieter van Braam
dffdf28349 X11 return to cwd at exit
During runtime godot calls chdir() several times. This doesn't really
matter normally but when using tools such as gprof the location of the
profiling data is kind of hard to intuit.

With this PR we simply store the current working directory at start and
restore it once we're almost done exiting.

This doesn't use the OS abstractions as when we need to get the current
workdir we haven't yet initialized it (by necessity). This would break
if we tried to build X11 for windows, but since the X11 target is
hardcoded to use the UNIX abstractions I don't think it matters.

(cherry picked from commit d0c2015fe1)
2017-03-18 20:12:42 +01:00
Vincent
02d711eb61 RichTextLabel add function remove_line
(cherry picked from commit c20b186e73)
2017-03-18 20:11:42 +01:00
Hein-Pieter van Braam
4cf49bb6f4 Allow preload to accept a const string.
In preload() parsing this code will lookup the identifier in the local
constant database. If the identifier corresponds to a string constant
it is used as the path for preload().

Currently this does not work for global constants, only constants
declared in the same class as the preload is happening. We can implement
a full fix too. Maybe we can use this PR to discuss the possibilities.

This (partially) fixes #6798

(cherry picked from commit 3e5743ca36)
2017-03-18 20:10:36 +01:00
Andreas Haas
674a090e59 Spinbox: don't ignore double clicks.
Fixes the problem with spinboxes not updating when clicking too fast.

(cherry picked from commit dd4c2709e4)
2017-03-18 20:09:55 +01:00
Hein-Pieter van Braam
38e86c8c24 Remove bounds check when resuming from yield.
The code would get a pointer to the beginning of the call_args by using
operator[] at the stack Vector. This does bound checking. When there are
no call_args this bound check fails and the error mentioned in #7796
gets triggered.

This bound check is actually not necessary as call_args just gets set to
NULL and never dereferenced. This new code will just unconditionally set
the pointer to the place where the call_args are if there are any. There
is no NULL check for call_args anywhere so this is safe.

Fixes #7796

(cherry picked from commit e8611966de)
2017-03-18 20:09:45 +01:00
Brett-Mitchell
616850b3c0 Fix for issue #7766
Add initialization for OS_OSX.mouse_mode in OS_OSX::OS_OSX().  mouse_mode now defaults to OS::MOUSE_MODE_VISIBLE.
(cherry picked from commit 6921e11805)
2017-03-18 20:09:45 +01:00
Andreas Haas
12a1b517ca ProjectSettings: InputMap dialog fixes
Now the selection jumps to the correct action after a new event has been added.
Also sets the default device id for Joypad button events to 0.

(cherry picked from commit 92ac7067e6)
2017-03-18 20:08:25 +01:00
Saracen
919c1d627f Fix glitches when sampling relative cursor data in CAPTURED mouse mode on Windows.
(cherry picked from commit 523b69771b)
2017-03-18 20:06:40 +01:00
Andreas Haas
fb2173174d Particles2D: implement texture flip parameters.
(cherry picked from commit 6a2dccaf77)
2017-03-18 20:06:11 +01:00
Hein-Pieter van Braam
c67b08300a Add a simple signal handler for SIGCHLD on Unix
This fixes #6631

(cherry picked from commit cff6840ff7)
2017-03-18 20:05:57 +01:00
Bojidar Marinov
9f536e3962 Make _sc_ files work like ._sc_, fixes #7762
(cherry picked from commit 27bb6b5282)
2017-03-18 20:04:00 +01:00
m4nu3lf
ca2277f3f1 Fixed property setter in G6DOF joint
(cherry picked from commit 0d9b53ce5e)
2017-03-18 19:58:23 +01:00
kbake
31260bb720 Selected text is now deselected on ctrl+home/end
This fixes Issue #7694 and also the error mentioned in the comments of that issue.

(cherry picked from commit 1169f4e040)
2017-03-18 19:58:13 +01:00
marcelofg55
97fef612fb Fix issues with set_window_resizable on x11
(cherry picked from commit 474e3ac055)
2017-03-18 19:56:16 +01:00
Chris Bradfield
c01c5fce59 grammar fixes, it's -> its
(cherry picked from commit 10176228b2)
2017-03-18 19:55:34 +01:00
Andreas Haas
6fb2abc7d8 SceneTreeDock: Fix crash when dragging invalid nodes.
Fixes #7529

(cherry picked from commit a64a348054)
2017-03-18 19:54:51 +01:00
Ferenc Arn
5e90183ba4 Use -Ofast on x11. Also introduced use_lto option.
debug_release doesn't turn off optimizations for release target now. Ensure that sanitizer options apply to both C and C++ files.

Built-in optimization/debug flags are prepended such that user-specified flags can override them.

Based on and around the discussion in PR #5194.

(cherry picked from commit 7a85d25218)
2017-03-18 19:52:35 +01:00
Ray Koopa
3f8ce209b7 Added warning when removing animations
(cherry picked from commit f279df2654)
2017-03-18 19:52:08 +01:00
Andreas Haas
8015ab0db3 Add ClassDB binding for File.get_modified_time
Closes #7613

(cherry picked from commit 5ec0610c60)
2017-03-18 19:46:36 +01:00
Geequlim
ca3881ccb8 Add 'Copy Node Path' action to right mouse menu
(cherry picked from commit 65db43d5ae)
2017-03-18 19:43:13 +01:00
Fabio Alessandrelli
b9451ce58d Fix gibberish output for windows/mingw.
%ls should be used instead of %s or %S to speficy narrow/wide charstring
in wprintf fwprintf

Fixes #6252

(cherry picked from commit 3df934acad)
2017-03-18 19:42:21 +01:00
volzhs
507bb0e1cb Change camera default rotation
(cherry picked from commit 0ecf7f7ca0)
2017-03-18 19:42:07 +01:00
Jerome67000
ab7faa1281 #7215 try to fix adb bad targeting user on device
(cherry picked from commit 8c19a6cb85)
2017-03-18 19:41:37 +01:00
Andreas Haas
1eb9925f58 CollisionShape2D: Fix warning icon not updating.
`CollisionPolygon2D` also had this problem.

(cherry picked from commit 16eee2f59b)
2017-03-18 19:32:02 +01:00
Ray Koopa
98f01f9143 Respect style boxes for Button states other than "normal"
(cherry picked from commit 2baeb531e6)
2017-03-18 19:31:43 +01:00
Jesper Bækdahl
e5f0183b0a x11: don't wait for window to be mapped
(cherry picked from commit 8f7a3884fd)
2017-03-18 19:29:46 +01:00
Rémi Verschelde
618ac3842e Merge pull request #8068 from Hinsbart/fix_ps_cross_2.1
InputMap: Rename joypad button "PS X" to "PS Cross". [2.1]
2017-03-18 14:52:59 +01:00
Andreas Haas
5cc184d732 InputMap: Rename joypad button "PS X" to "PS Cross". 2017-03-18 12:36:53 +01:00
Rémi Verschelde
b5be9d6115 Merge pull request #8038 from RandomShaper/remove-warning-2.1
Remove warning on owner re-assignment (2.1)
2017-03-18 10:49:35 +01:00
Rémi Verschelde
58455f03f7 Merge pull request #8031 from RandomShaper/fix-redundant-connections-2.1
Fix redundant connections (2.1)
2017-03-18 10:46:59 +01:00
Pedro J. Estébanez
7b27cc91b1 Remove warning on owner re-assignment 2017-03-15 12:28:38 +01:00
Pedro J. Estébanez
148566b31b Fix redundant connections saved in sub-inheritance 2017-03-15 11:48:24 +01:00
Pedro J. Estébanez
6289997724 Fix ambiguity in StringName (null data vs. data with empty string) 2017-03-15 04:26:23 +01:00
Rémi Verschelde
8ea4413a2c Merge pull request #8016 from RandomShaper/optimize-assert-2.1
Skip asserts on non-debug builds at compiler level (2.1)
2017-03-13 11:08:47 +01:00
Rémi Verschelde
c185fe1095 Merge pull request #7991 from BastiaanOlij/CoreMotion_2.1
Core motion for Godot 2.x (based on PR 7127)
2017-03-13 11:03:31 +01:00
Rémi Verschelde
ce09a094ab Merge pull request #7987 from RandomShaper/fix-touch-button-2.1
Several fixes for TouchScreenButton (2.1)
2017-03-13 11:02:50 +01:00
Rémi Verschelde
3c566fc552 Merge pull request #7978 from RandomShaper/fix-sub-inheritance-2.1
Fix node duplication in scene sub-inheritance (2.1)
2017-03-13 11:00:59 +01:00
Rémi Verschelde
e869a8a279 Merge pull request #7969 from RandomShaper/pr-7565-polish
PR 7565 + polish
2017-03-13 11:00:20 +01:00
Rémi Verschelde
91cf3c1321 Merge pull request #7957 from RandomShaper/fix-kb-2d-motion-2.1
Fix KinematicBody2D motion issues + KinematicBody2D.test_move_from() (2.1)
2017-03-13 10:59:53 +01:00
Pedro J. Estébanez
204a7481e0 Skip asserts on non-debug builds at compiler level 2017-03-13 00:23:42 +01:00
Pedro J. Estébanez
3be30efe8e Fixes for TouchScreenButton
- getting stuck on pause
- handling input when not visible
2017-03-10 14:11:54 +01:00
BastiaanOlij
8436a34305 Core motion for Godot 2.x (based on PR 7127) 2017-03-09 21:46:38 +11:00
Pedro J. Estébanez
6aef1c48c4 Fix node duplication in scene sub-inheritance 2017-03-08 19:58:59 +01:00
Rémi Verschelde
50c6a6d9b1 Merge pull request #7977 from eska014/2.1-web-window
Backport all web 'window' features to 2.1
2017-03-08 07:28:38 +01:00
eska
9518401100 Add window features in web export
- Add 'window' (canvas) resize, maximize and fullscreen
 - Implement get_screen_size
 - Fix fullscreen resolution

(cherry picked from commit 3e1b437315)
2017-03-07 14:11:00 +01:00
eska
d34c530a7f Revert "Add fullscreen features in web export"
This reverts commit 17422f1f86.
2017-03-07 14:11:00 +01:00
Pedro J. Estébanez
1e79f80b90 Finish fix for POSITION in 2D shaders 2017-03-06 18:31:29 +01:00
Pedro J. Estébanez
95a5d9e617 Fix KinematicBody2D wrong motion origin
Got part of the fix from 5fc084c28e
Added an engine setting to enable the fix (physics_2d/motion_fix_enabled) which is false by default so the default behavior is the same as always
Added motion methods with a from parameter, the same as 3.0 does
2017-03-06 05:10:15 +01:00
Rémi Verschelde
cc265d5506 Merge pull request #7910 from RandomShaper/single-field-prop-edit-2.1
Implement single-field property change for multinode edit (2.1)
2017-03-05 13:43:35 +01:00
Rémi Verschelde
bfa3d70169 Travis: Disable Android builds for now
As we say in French, "Trop, c'est trop !".
Those builds fail 50% of the time due to timeouts, it's pointless to have them until we
find a better solution to install the Android SDK and NDK.

Workaround for #6973.
(cherry picked from commit d5c6806e16)
2017-03-05 13:40:45 +01:00
Rémi Verschelde
0f5b85f85a Merge pull request #7949 from RandomShaper/expose-more-geom-2.1
Expose uncapped versions of closest-point-to-segment utilities (2.1)
2017-03-05 12:04:20 +01:00
Rémi Verschelde
eeca4a3aa3 Merge pull request #7933 from RebelliousX/2.1
TabContainer's signal changes (v2.1)
2017-03-05 12:03:38 +01:00
Thaer Razeq
886f150b4a - Added tab_selected signal which has same behavior as tab_changed
lest breaking current API, though, it is noted in the documentation of TabContainer
class, of the upcoming Godot (v3.0+) changes in behavior, that is, `tab_selected` will be
emitted for selecting any tab, while `tab_changed` only if a tab changes.
- Added `get_previous_tab()`. Which returns the previous shown tab. **Note:** In Godot v3.0+, only `tab_changed` can modify previous tab index.
- Add documentation for the added function and signals. Fix a typo too.
2017-03-05 03:26:53 -06:00
Pedro J. Estébanez
e0170625ef Expose uncapped versions of closest-point-to-segment utilities 2017-03-04 22:57:53 +01:00
Rémi Verschelde
bc56fa8d91 Merge pull request #7941 from RandomShaper/expose-geometry-2.1
Expose Geometry::get_closest_point_to_segment_2d() (2.1)
2017-03-04 17:00:45 +01:00
Rémi Verschelde
e5a458d8d0 Merge pull request #7936 from volzhs/fix-input-android-2.1
Fix handling input for Android (2.1)
2017-03-04 16:59:58 +01:00
Rémi Verschelde
c58c490d45 Merge pull request #7934 from lonesurvivor/area2d-fix_2.1
2.1: Fixes two problems with Area2D and remove_child()
2017-03-04 16:57:23 +01:00
Rémi Verschelde
9cf5058610 Merge pull request #7926 from volzhs/issue-7902
Fix wrong TreeItem reference after reconstructing (2.1)
2017-03-04 16:47:58 +01:00
Pedro J. Estébanez
25aedb896a Expose Geometry::get_closest_point_to_segment_2d() 2017-03-04 01:49:16 +01:00
volzhs
c8edf071da Fix handling input for Android 2017-03-04 00:12:35 +09:00
lonesurvivor
5b556cab25 Fixes two problems with Area2D and remove_child()
- When one of two or more overlapping Area2Ds is removed with remove_child(), it doesn't try to report to the
other one anymore
- When overlappinng Area2Ds are removed woth remove_child(), _enter_tree and _exit_tree signals are now
properly disconnected upon removal
2017-03-03 11:36:50 +01:00
volzhs
4a8d2b676e Fix wrong TreeItem reference after reconstructing 2017-03-03 03:51:23 +09:00
Pedro J. Estébanez
e46e12906a Implement single-field property change for multinode edit 2017-03-02 10:48:24 +01:00
Rémi Verschelde
43574f65da Merge pull request #7909 from RandomShaper/cp-tileset-modulate-2.1
Cherry-pick modulate (color) for TileSet tiles (2.1)
2017-03-01 10:08:01 +01:00
Pedro J. Estébanez
b6721caa13 Add modulate (color) to TileSet tiles
(cherry picked from commit 86789c7071)
2017-03-01 03:21:47 +01:00
Rémi Verschelde
d79f44da62 Merge pull request #7852 from volzhs/cache-font-2.1
Cache DynamicFont resource for Android (2.1)
2017-02-27 23:35:35 +01:00
Rémi Verschelde
ee9f31a5cc Merge pull request #7716 from GodotExplorer/pr-resizable-texturebutton
[2.1] Enhance TextureButton and TextureFrame with resize
2017-02-27 23:30:53 +01:00
Rémi Verschelde
e9e5affda1 Merge pull request #7896 from RandomShaper/particles2d-process-mode-2.1
Add process mode option to Particles2D (2.1)
2017-02-27 14:03:46 +01:00
Pedro J. Estébanez
7e90b98db2 Add process mode option to Particles2D 2017-02-27 10:45:06 +01:00
Rémi Verschelde
f67881bada Merge pull request #7873 from volzhs/issue-7820
Fix crash when click icon while editing node name (2.1)
2017-02-26 20:27:53 +01:00
Rémi Verschelde
6490e9ae5b Merge pull request #7868 from RandomShaper/fix-touchbutton-crash-2.1
Fix crash if TouchScreenButton is pressed while exiting the tree (2.1)
2017-02-26 20:27:35 +01:00
Rémi Verschelde
902288cc8c Merge pull request #7855 from RandomShaper/add-duplicate-flags-2.1
Add flags parameter to Node.duplicate()
2017-02-26 20:23:55 +01:00
Rémi Verschelde
02a3d08d93 Merge pull request #7829 from volzhs/libwebp-0.6.0-2.1
Update libwebp to 0.6.0 (for 2.1)
2017-02-26 20:14:44 +01:00
volzhs
3d817ac73a Fix crash when click icon while editing node name 2017-02-23 02:16:49 +09:00
volzhs
71a5b0885b Cache DynamicFont resource for Android 2017-02-22 22:54:19 +09:00
Pedro J. Estébanez
5b8d5766f4 Fix crash if TouchScreenButton is pressed while exiting the tree 2017-02-22 01:36:31 +01:00
Pedro J. Estébanez
bbbc3a91c9 Add flags parameter to Node.duplicate()
to decide whether signals, groups and/or scripts should be set in the copied nodes or not; it's default value makes the method work as usual, that is, including everything
2017-02-20 19:43:26 +01:00
volzhs
f7ef78c998 Update libwebp to 0.6.0 2017-02-18 00:05:06 +09:00
Juan Linietsky
d5c2a6b76b Godot 2.1 to 3.0 conversion should be more or less final 2017-02-15 08:29:11 -03:00
geequlim
a7ec7dcd12 Add scale property back for backwards compatibility
now we have a choice
Fix textureframe modulate doesn't work with STRETCH_KEEP_ASPECT_CENTERED and STRETCH_KEEP_ASPECT
2017-02-13 20:04:21 +08:00
Juan Linietsky
ebb7d2cdb7 -WIP Exporter to Godot 3.0, only text scenes (no .scn) and still kind of buggy 2017-02-12 23:13:14 -03:00
Rémi Verschelde
6abe141579 Merge pull request #7756 from volzhs/str-format
Fix zero padding formatting
2017-02-12 23:20:13 +01:00
Rémi Verschelde
f50b4f5cb2 Merge pull request #7754 from volzhs/tr-buttonarray
Translate ButtonArray text
2017-02-12 23:19:52 +01:00
Rémi Verschelde
eff8fc4dfb Merge pull request #7751 from bojidar-bg/sort-scripts-by-path-2.1
Sort settings for scripts in the editor (2.1)
2017-02-12 23:19:28 +01:00
Rémi Verschelde
11b95cda45 Merge pull request #7750 from Faless/2.1.x_fix_7697
HTTPClient properly handle partial data in non-blocking mode
2017-02-12 23:19:10 +01:00
Rémi Verschelde
331ff9db77 Merge pull request #7742 from karroffel/json_parsing
JSON::parse reports errors on open-ended objects
2017-02-12 23:17:11 +01:00
Rémi Verschelde
3b09d77208 Merge pull request #7721 from RandomShaper/improve-touch-button-2.1
Fix touch button issues (2.1)
2017-02-12 23:12:14 +01:00
Rémi Verschelde
4e9f88b649 Merge pull request #7719 from RandomShaper/backport-code-edit-goodies-2.1
Backport goodies for the code editors (2.1)
2017-02-12 23:11:31 +01:00
Pedro J. Estébanez
c0f7b80b89 Solve TouchScreenButtons issues
Fix touch button needing double tap after pause (applies to those not set to pass-by)
Fix error when a pressed TouchScreenButton with no associated action exits the tree
(with some refactoring of duplicate code)
2017-02-10 20:53:35 +01:00
Nuno Donato
7496b2f862 Added "Scots" locale name, fixing #7630
(cherry picked from commit 6b5c595e40)
2017-02-08 16:18:59 +01:00
Rémi Verschelde
9e3f063e99 Revert "Fixes #7630 Hint was be appending for every language. Changed to only fill hint with the matching language."
This reverts commit b6468db118,
the bug will be properly fixed by the cherry-pick of 6b5c595.
2017-02-08 16:18:22 +01:00
volzhs
7ebb356a31 Fix zero padding formatting 2017-02-08 10:40:35 +09:00
volzhs
e0f00a549c Translate ButtonArray text 2017-02-08 08:38:36 +09:00
Bojidar Marinov
9fa3713d76 Sort settings for scripts in the editor 2017-02-07 18:57:49 +02:00
Rémi Verschelde
be0350704f Merge pull request #7711 from williamd1k0/cherrypick-colorframe
Add ColorFrame control (2.1)
2017-02-07 14:16:47 +01:00
Fabio Alessandrelli
1f08d17a98 HTTPClient properly handle partial data in non-blocking mode
Use block to send DVector::Write out of scope in
HTTPClient::read_response_body_chunk()

(cherry picked from commit 833994b294)
2017-02-07 11:05:14 +01:00
Karroffel
85793ccc4a JSON::parse reports errors on open-ended objects 2017-02-06 19:22:42 +00:00
Pedro J. Estébanez
0dbfb864ad Backport goodies for the code editors
Refactor duplicated code (from 0159e4f969)
Add line length guideline to code editors (from d9c1729a8f)
Allow turning off zero-padding for line numbers (from 00b3af246b)
(In 3.0 zero-padding is off by default, but for 2.1 I'm setting the default to be on because it's how it always worked.)
Fixed line lenght guideline drawing with color option (from @Paulb23's 6b42cd5fe6)
2017-02-04 16:24:33 +01:00
geequlim
58a700e43e Make same resize behavior for TextureButton with TextureFrame.
Remove property 'scale' of TextureButton which is not required any more.
2017-02-04 14:56:26 +08:00
geequlim
0c1c34ef22 Add Keep Covered texture resize mode 2017-02-04 14:26:50 +08:00
William Tumeo
f3bc5d443c Add ColorFrame control (2.1)
- cherry-pick from 95eb7466df
2017-02-02 18:22:03 -02:00
Rémi Verschelde
34b6caa433 Merge pull request #7678 from volzhs/fix-save-branch
Fix crash when saving root node by "Save Branch as Scene" with unsaved scene
2017-02-02 08:15:28 +01:00
Rémi Verschelde
6a01cf96b2 Merge pull request #7671 from RandomShaper/load-placeholder-dup-2.1
Replicate load-as-placeholder state on node duplication (2.1)
2017-02-02 08:14:02 +01:00
Rémi Verschelde
1d0997b01e Merge pull request #7660 from zombieCraig/translationfix
Fixes #7630  Editor Translation Import Crash fix
2017-02-02 08:11:39 +01:00
Rémi Verschelde
bd71020354 Merge pull request #7651 from leezh/collada_import_tweaks
Re-Implemented Texture Actions for Scene Import (2.1 Branch)
2017-02-02 08:10:10 +01:00
Rémi Verschelde
6b1d33ec71 Merge pull request #7650 from pkowal1982/fix_7011
Fix #7011 ScrollContainer takes into account child's EXPAND flag when scrolling is enabled
2017-02-02 08:09:09 +01:00
Rémi Verschelde
4a73e74ccb Merge pull request #7641 from RandomShaper/touch-button-shape
Touch button shape (2.1)
2017-02-02 08:05:26 +01:00
volzhs
43a2599801 Fix crash when saving root node by "Save Branch as Scene" with unsaved scene
Fix #7667
2017-01-30 07:00:03 +09:00
Pedro J. Estébanez
936f2e3b4e Replicate load-as-placeholder state on node duplication (2.1) 2017-01-29 11:50:42 +01:00
Craig Smith
b6468db118 Fixes #7630 Hint was be appending for every language. Changed to only fill hint with the matching language. 2017-01-27 22:43:44 -08:00
Pawel Kowal
e9316a009e Fix #7011 ScrollContainer takes into account child's EXPAND flag when scrolling is enabled 2017-01-26 10:02:19 +01:00
Zher Huei Lee
f3b32746de Re-Implemented Texture Actions for Scene Import
Moved the shared_textures config to the editor category so that it would
be visible in the project settings window again. Fixes #7579

Added option to import textures to the same folder as the source
textures, or to reuse the files without re-importing (flags may need to
be applied manually).
2017-01-26 16:44:27 +08:00
Rémi Verschelde
cdb0be8eed Merge pull request #7646 from RandomShaper/vcs-friendliness-2.1
Improve .tscn VCS (2.1)
2017-01-25 20:56:17 +01:00
Rémi Verschelde
ad899a0dd9 Merge pull request #7639 from volzhs/fix-scrollbar-2d-editor-2.1
Fix weird scrollbar appearance on 2D editor (2.1)
2017-01-25 20:39:45 +01:00
Pedro J. Estébanez
888f8b31e7 Improve .tscn VCS
Serialize dictionaries adding newlines between key-value pairs
Serialize group lists also with newlines in between
Serialize string properties escaping only " and \ (needed for a good diff experience with built-in scripts and shaders)

Bonus:
Make AnimationPlayer serialize its blend times always sorted so their order is predictable in the .tscn file.

This PR is back-compat; won't break the load of existing files.

Cherry-picked from 7dbb1c0571
2017-01-25 20:11:10 +01:00
Pedro J. Estébanez
67a0da34a2 Add shape property to TouchScreenButton 2017-01-25 17:06:06 +01:00
volzhs
5b2c31a18a Fix weird scrollbar appearance on 2D editor (2.1) 2017-01-25 23:34:41 +09:00
Rémi Verschelde
9038a96e49 Merge pull request #7632 from RandomShaper/hide-lock-icons-2.1
2D Editor: Don't show lock icons for hidden nodes (2.1)
2017-01-25 07:38:16 +01:00
Rémi Verschelde
e4efab04bb Merge pull request #7634 from RandomShaper/fs-split-layout-2.1
Include filesystem dock split offset in editor layouts (2.1)
2017-01-25 07:37:45 +01:00
Pedro J. Estébanez
2ac89f6540 Include filesystem dock split offset in editor layouts 2017-01-25 02:46:44 +01:00
Andreas Haas
8f11304dfc 2D Editor: Don't show lock icons for hidden nodes.
Now we only draw those icons for visible Nodes.
Fixes #7518

Cherry-picked/adapted from a043ce7304
2017-01-25 00:58:14 +01:00
Rémi Verschelde
6549733aa7 Merge pull request #7625 from RandomShaper/fix-android-module-res
Fix resources for Android modules not being merged (2.1)
2017-01-25 00:04:40 +01:00
Pedro J. Estébanez
fec41c528c Fix resources for Android modules not being merged
Fixes #7421
2017-01-24 16:29:09 +01:00
Rémi Verschelde
c508b5b2e1 Release 2.1.2-stable 2017-01-21 14:43:37 +01:00
Rémi Verschelde
b65e553440 classref: Sync with current source 2017-01-21 14:06:17 +01:00
Rémi Verschelde
7c47769aa2 Remove Quick Filter Files and fix FS search hotkey
The new Quick Filter Files behaviour since 8b47e26 had not been implemented,
so this implements it and makes it an editor hotkey instead of a menu entry.
Fixes #7582.

(cherry picked from commit c4d6e54e93)
2017-01-21 13:44:27 +01:00
saltpowered
6a62831195 fix for https://github.com/godotengine/godot/issues/3226 2017-01-17 01:05:58 -06:00
Rémi Verschelde
0669c9816e Merge pull request #7557 from RandomShaper/ordered-image-group-files-2.1
Make image-groups map in export.cfg ordered (2.1)
2017-01-16 21:05:28 +01:00
Rémi Verschelde
23789f49dd Merge pull request #7561 from eska014/web-presentation-2.1
Cherry-pick usability fixes in web export presentation
[ci skip]
2017-01-16 20:13:19 +01:00
Pedro J. Estébanez
8e380677cb Make image-groups map in export.cfg ordered
This improves the VCS experience because otherwise they change their order everytime producing spurious changes.
2017-01-16 19:00:48 +01:00
eska
e4bbc1067a Improve usability in web export presentation
- Make canvas support check message visible
 - Make it obvious status can be closed by clicking
 - Don't use status to display non-critical errors
 - Fix setting total memory

(cherry picked from commit 1f7d4c4d0e)
2017-01-16 18:39:04 +01:00
Rémi Verschelde
5aac8eeb0f Merge pull request #7549 from RandomShaper/cp-usability-2.1
Cherry-pick node creation usability enhancements (2.1)
2017-01-16 18:05:56 +01:00
Rémi Verschelde
b351d4cbc1 zlib: Update to upstream version 1.2.11
(cherry picked from commit 6a3dae5be9)
2017-01-16 17:58:43 +01:00
Rémi Verschelde
1f2293d5cc Merge pull request #7554 from Faless/2.1-tcp-winfix
2.1.x - Fix bug in windows TCP poll function
2017-01-16 16:00:27 +01:00
Fabio Alessandrelli
8322c1aa64 Fix bug in windows TCP poll function
Bug introduced when implementing TCP disconnection detection.
(too much yank-paste).
Fixes #7545

(cherry picked from commit c356ec5e8b)
2017-01-16 15:51:43 +01:00
Pedro J. Estébanez
8fca6870c4 Added favorites and recent history to create dialog
Cherry-picked from 8d785812351a0a3eca88214f2436bb7574d55873 and 827a9aa829
2017-01-16 12:38:46 +01:00
Juan Linietsky
9f3c594f9e Making bits of docs appear in different dialogues is made easier with EditorHelpBit 2017-01-16 11:56:00 +01:00
Pedro J. Estébanez
b3d0596c4b Add EditorNode::set_visible_editor()
Cherry-picked from d8af6330e5
2017-01-16 11:56:00 +01:00
Rémi Verschelde
6b5a852bd8 Merge pull request #7522 from Faless/2.1-split
2.1.x Cherry pick patch to enable 2D split screen. ( #6486 )
2017-01-16 10:11:39 +01:00
Juan Linietsky
25a62a3e32 Added a few functions to make 2D split screen easier.
(cherry picked from commit a4156f1f0a)
2017-01-12 20:53:03 +01:00
Fabio Alessandrelli
b61d7e6261 Restore viewport set_world_2d functionality
(cherry picked from commit 97cf3eba56)
2017-01-12 19:44:22 +01:00
Fabio Alessandrelli
9c8ecb45f8 Improvements to scons defined WINVER/_WIN32_WINNT
(cherry picked from commit 65483d57bf)
2017-01-12 19:15:30 +01:00
Ignacio Etcheverry
8a5596322d Detect bits when building with MinGW
(cherry picked from commit 460f030b73)
2017-01-12 19:15:30 +01:00
Rémi Verschelde
93a83c81f0 Windows: Workaround missing includes in MinGW-w64 < 4
The MinGW-w64 version we have on our Travis build environment (Ubuntu 12.04,
mingw-w64 2.0.1, gcc 4.6) is old and has some missing includes in the
dependencies of the `tcpmib.h` header [0] [1] [2].
Those were not triggered before 6323779596
probably due to conflicting WINVER definitions which prevented triggering the code
specific to >= 0x0600 (Vista). We ensure it won't be triggered by defining the
_WIN32_WINNT macro to Windows XP compatibility.
(cherry picked from commit b24fe6879a)
2017-01-12 19:15:30 +01:00
Rémi Verschelde
af7fd899f4 opus: Update to upstream opusfile 0.8
Had missed it in the previous commit as the upstream website is outdated.

(cherry picked from commit c2310b41fa)
2017-01-12 19:15:30 +01:00
Rémi Verschelde
d66740175e Windows: Define _WIN32_WINRT to 0x0600 (Vista)
Passed as a compiler define to be sure it is always define before windows.h
is loaded. This means that Godot officially requires Vista API or later, it will
not work on Windows XP or earlier.

Also fix a bogus check for Windows 7 API.

(cherry picked from commit 6323779596)
2017-01-12 19:15:30 +01:00
Rémi Verschelde
5672852351 x11: Improve logic for cross-dependencies between freetype, zlib and libpng
Fixes #7373.

(cherry picked from commit d945c4e58e)
2017-01-12 19:15:30 +01:00
Rémi Verschelde
349e62835b i18n: Add support for Scots (sco) language
Fixes #6931.

(cherry picked from commit ede36aca8d)
2017-01-12 19:15:30 +01:00
Rémi Verschelde
ff490e42da Move core engine tests to main
(cherry picked from commits 790f629e5e
and 8b7a86ec7b)
2017-01-12 19:15:30 +01:00
karroffel
b1fc41a301 exposed OS.set_exit_code and OS.get_exit_code to ObjectTypeDB
(cherry picked from commit fbfcc981d9)
2017-01-12 19:15:30 +01:00
Rémi Verschelde
3cd976366e opus: Update to upstream libopus 1.1.3
(cherry picked from commit 9845bdde8d)
2017-01-12 19:15:30 +01:00
Rémi Verschelde
6e9584e0c5 zlib: Update to upstream 1.2.10
(cherry picked from commit 2ca0337f5f)
2017-01-12 19:15:30 +01:00
Rémi Verschelde
c24c2ca17b libpng: Update to upstream 1.6.28
Fixes a NULL pointer dereference bug (CVE-2016-10087).

(cherry picked from commit a0141fa823)
2017-01-12 19:15:30 +01:00
lonesurvivor
d2240404e3 Fix for the huge audio latency of the SamplePlayer (>200 ms)
- fixes PulseAudio, ALSA and RtAudio driver
- cleans up the driver files for better readability (mostly whitespace-related stuff)
- makes ALSA and Pulseaudio actually use the global setting "audio/mix_rate" for the sample rate instead of a
fixed value (RtAudio did this already)

(cherry picked from commit da6b6c2dd7)
2017-01-12 19:15:30 +01:00
Bruno Ortiz
01b8beb023 Making deselect work for TreeItem when select_mode is SELECT_SINGLE and item_selected is now properly emitted
(cherry picked from commit 4b9a96859b)
2017-01-12 19:15:30 +01:00
Bruno Ortiz
4f35fdd1e3 Exposing edit_resource method of EditorNode in the EditorPlugin (#7355)
(cherry picked from commit 7e0d0d0bb9)
2017-01-12 19:15:30 +01:00
Wilhem Barbier
0b6d4e92b5 Add the 'finished' signal to AnimatedSprite
(cherry picked from commit f6262fde11)
2017-01-12 19:15:30 +01:00
Rémi Verschelde
d8223ffa75 Welcome in 2017, dear changelog reader!
That year should bring the long-awaited OpenGL ES 3.0 compatible renderer
with state-of-the-art rendering techniques tuned to work as low as middle
end handheld devices - without compromising with the possibilities given
for higher end desktop games of course. Great times ahead for the Godot
community and the gamers that will play our games!

(cherry picked from commit c7bc44d5ad)
2017-01-12 19:15:30 +01:00
Ignacio Etcheverry
b5bdc60f58 TileMap: _update_dirty_quadrants() cancel pending update pre return
(cherry picked from commit 5b3acd287d)
2017-01-12 19:15:29 +01:00
Marc Gilleron
ba50bb9cb1 Added option to toggle bucket fill preview
(cherry picked from commit 39771f22b6)
2017-01-12 19:15:29 +01:00
Marc Gilleron
2a60bf1cd9 Added bucket fill preview
(cherry picked from commit 36d0281a2b)
2017-01-12 19:15:29 +01:00
ktksgit
1bb1b6986c Update DebugMesh when NavMesh changes
Fixes #7371
(cherry picked from commit 2807507325)
2017-01-12 19:15:29 +01:00
Bojidar Marinov
4c9c43735a Disallow assignment to expressions
Fixes #6824

(cherry picked from commits 0b077162a3
and dcc4ee21c1)
2017-01-12 19:15:28 +01:00
Fabio Alessandrelli
6940830627 Properly localize absolute path.
Calling localize_path will return a localized path in res:// if the
path starts with the resource file-system/folder, and will return
the unchanged absolute path otherwise.

Closes #6979 and #7161.

(cherry picked from commit cdc97ca453)
2017-01-12 19:15:28 +01:00
Bojidar Marinov
27a801df99 Fix #7098 by not accepting right clicks while dragging the range
(cherry picked from commit d40eb1565e)
2017-01-12 19:15:28 +01:00
volzhs
f520e7788e Show visual notice for visibility on Scene Dock
(cherry picked from commit f33e21e7af)
2017-01-12 19:15:28 +01:00
volzhs
580031e6f5 Able to change visibility when ancestor node is hidden
(cherry picked from commit 792ff11642)
2017-01-12 19:15:28 +01:00
volzhs
d5e4011bc3 Scroll horizontally with mouse wheel when horizontal enabled only
(cherry picked from commit 22b76511fb)
2017-01-12 19:15:28 +01:00
chanon
1397019424 fix ColorPicker not correctly updating after pasting hex html color
(cherry picked from commit 0bf5d86546)
2017-01-12 19:15:28 +01:00
Guilherme Felipe
eea6c43676 Add new option to always open output on play
(cherry picked from commit faf6f865dd)
2017-01-12 19:15:28 +01:00
Guilherme Felipe
3a4c412153 Fix visibility of bottom panel when start playing
(cherry picked from commit 83b82fc267)
2017-01-12 19:15:28 +01:00
Elia Argentieri
9b0be3753b Expose set_bone_name and get_bone_name to GDscript
(cherry picked from commit b96e2e1126)
2017-01-12 19:15:28 +01:00
volzhs
5698571235 Update libwebp to 0.5.2
(cherry picked from commit e04c7e11ec)
2017-01-12 19:15:28 +01:00
Ivan P. Skodje
0701e7c2d8 PopupMenu upgrade: Hide on item selection (#7306)
* Added the option to set hide on item selection. Usable in GDScript and from within the source code when you want to specify popup menus you don't want to close immediately when selecting an item

* Renamed getter from get_ to is_, fixed parent/child behavior, renamed bool variable to match most code and added ADD_PROPERTYNO to save some memory

(cherry picked from commit da950cd0f2)
2017-01-12 19:15:28 +01:00
REBELLIOUSX\Rebel_X
2fbae72d14 Fix issue #7331
A Drive with "Z" letter assigned to it on Windows will be shown.

(cherry picked from commit 20d6af6028)
2017-01-12 19:15:28 +01:00
volzhs
dbeb1ca114 Fix duplicated string on RichTextLabel if starts with '\n'
Fix #6212, #3773

(cherry picked from commit 0ecc968c5c)
2017-01-12 19:15:28 +01:00
bebae
0aebdb346a Allows to start the scene with custom arguments within the editor
fixes #7346

Path from the current scene isn't added too the argumens anymore by default and needs to be added throug the custom arguments, with $scene. Matches the behaviour of the executable without any arguments.
Custom Arguments are read from editor/main_run_args

(cherry picked from commit abdedc3522)
2017-01-12 19:15:28 +01:00
Bojidar Marinov
71b35c527f Remove extraneous line in .po reader, which caused it to disregard first line
Fixes #7337

(cherry picked from commit 474eafbbf6)
2017-01-12 19:15:28 +01:00
Ignacio Etcheverry
a282579f5c Register SpatialGizmo as a scene type
(cherry picked from commit ce41464fc0)
2017-01-12 19:15:27 +01:00
Johnson Earls
f08aa02688 Fix search to find "whole" words at end of line
Fix `_get_column_pos_of_word` so that the `SEARCH_WHOLE_WORDS` flag will properly find words that are at the end of a line.

Fixes #7326 .
(cherry picked from commit d1cf29fe99)
2017-01-12 19:15:27 +01:00
Jerome67000
a8bc2f64ad doc improvement for get_colliding_bodies() methods
(cherry picked from commit 3cd5c86b1a)
2017-01-12 19:15:27 +01:00
Bojidar Marinov
85585c7fc5 Add named colors to GDScript/core.
Names and values taken from https://en.wikipedia.org/wiki/X11_color_names

(cherry picked from commit 23381a530b)
2017-01-12 19:15:27 +01:00
Bojidar Marinov
c5bff5073e Fix #7303, Quad node mesh data leak
(cherry picked from commit 7504a015aa)
2017-01-12 19:15:27 +01:00
Gustav Lund
f10a78e5c0 fix for crash when no ALSA or Pulse installed on linux
(cherry picked from commit 2495e8a941)
2017-01-12 19:15:27 +01:00
Ignacio Etcheverry
5354d7ddcc KinematicBody: Fix wrong method bind return type
(cherry picked from commit d579d0a814)
2017-01-12 19:15:27 +01:00
Patrick Reh
ff3891f88e small improvement to y_sort: make clear which item has to be drawn first when two have the same y-coordinate
(cherry picked from commit 4118b21e43)
2017-01-12 19:15:27 +01:00
Andreas Haas
5bfd0bbe5e TextureRegionEditor: Fix mouse wheel scroll speed.
Any given mouse wheel input will generate two InputEvents in godot.
The zoom methods here acted on both ones, effectively giving a step value of 4 instead of 2.
Fixes #7236

(cherry picked from commit c2040324be)
2017-01-12 19:15:27 +01:00
Andreas Haas
fa816730c0 Curve2D/3D: Add clear_points method.
Adds a method to the Curve2D and Curve3D classes to easily clear the curve.
So you don't have to remove each point manually.

(cherry picked from commit e741da869a)
2017-01-12 19:15:27 +01:00
Andreas Haas
01f3399ed0 Particles2D: Fix initial size randomness property having no effect.
It was just a little typo :p

(cherry picked from commit 4dd6bead1f)
2017-01-12 19:15:27 +01:00
Andreas Haas
1e34e8d5e1 Fix crash on project importing by dragging a folder.
Fixes #7226

(cherry picked from commit d82c2687f3)
2017-01-12 19:15:27 +01:00
volzhs
f184455187 Show selected node in Scene dock when parent node is folded
Fix #7228

(cherry picked from commit a192e0785e)
2017-01-12 19:15:27 +01:00
volzhs
c07fe5e8de Check keystore field when export Android release apk
(cherry picked from commit 36b4b45170)
2017-01-12 19:15:27 +01:00
Rémi Verschelde
5b27f05e7e Fix console output for MinGW compilers
Reworked patch from @jay3d (#7116).
(cherry picked from commit f28ff8a208)
2017-01-12 19:15:27 +01:00
volzhs
2e74bdab35 Add alert window on Android
(cherry picked from commit 9a20068ab7)
2017-01-12 19:15:26 +01:00
volzhs
916e79a5bf Fix scroll bar moving in AnimationPlayer editor
Fix #7196

(cherry picked from commit babc5048dd)
2017-01-12 19:15:26 +01:00
volzhs
f95694ee86 Fix color selected with mouse scroll
Fix #7192

(cherry picked from commit d9048309e4)
2017-01-12 19:15:26 +01:00
Dmitry Kram
6227e8f343 Fix snap mode selector sticking in texture region module
When changing snap mode in texture region plugin ticks was not updating. Issue fixed changing order of setting checked status and setting snap mode.

(cherry picked from commit d766738991)
2017-01-12 19:15:26 +01:00
volzhs
608e3f3097 Prevent Spinbox value update while not focused or disabled
(cherry picked from commit 4df33cbcb3)
2017-01-12 19:15:26 +01:00
BastiaanOlij
ef009a8b91 Set minimum version to 10.9 building OSX
(cherry picked from commit da5651fbb9)
2017-01-12 19:15:26 +01:00
romeojulietthotel
1a41d3351a Correct description for the return values from get_status. (#7137)
(cherry picked from commit f8d523b68b)
2017-01-12 19:15:26 +01:00
Zher Huei Lee
17399de0e1 Reused Button styleboxes for ButtonArray
Plus other tweaks to make it look more similar to a VBoxContainer of
Buttons.

(cherry picked from commit 191fdc873e)
2017-01-12 19:15:26 +01:00
Zher Huei Lee
fe81402257 Flat button support in ButtonArray. Fixes #7153
(cherry picked from commit 4b7443aeea)
2017-01-12 19:15:26 +01:00
Kazuo256
b56c00cc56 Add Array.front() and Array.back()
(cherry picked from commit bf4fda64fd)
2017-01-12 19:15:26 +01:00
Bojidar Marinov
13cdc2a6f5 Guard agains duplicate calling of _ready when instanced in _enter_tree
Fixes #6005

(cherry picked from commit 184173a9b9)
2017-01-12 19:15:26 +01:00
volzhs
fd5e01d1cd Select exactly matched file automatically in FileDialog
(cherry picked from commit ff4f04e878)
2017-01-12 19:15:26 +01:00
Rémi Verschelde
b328d2eb00 Merge pull request #7494 from RandomShaper/cherry-pick-backcompat-stuff
Cherry pick backcompat stuff (2.1)
2017-01-11 10:35:36 +01:00
Rémi Verschelde
fde651ebf8 Merge pull request #7495 from RandomShaper/more-uniform-reuse-fix
More uniform reuse fix (2.1)
2017-01-11 10:34:41 +01:00
Emmanuel Leblond
39ce4a49fa Add Node2D's set_global_rot get_global_rot set_global_rotd get_global_rotd set_global_scale get_global_scale methods. 2017-01-10 17:15:28 +01:00
Bojidar Marinov
6ad84850ab Ternary operator in GDScript (a if x else b)
Fixes #1961
2017-01-10 17:09:26 +01:00
Bojidar Marinov
c0743f898a Allow for linebreaks in function calls and definitions and yeild/signal.
(Plus maybe a few other things)
2017-01-10 17:08:50 +01:00
Pedro J. Estébanez
8589a1b117 Fix uniforms with the same name shadowing others
Follow-up of #7344
2017-01-10 17:05:31 +01:00
Rémi Verschelde
40de567297 classref: Sync with current code 2017-01-08 12:36:38 +01:00
Emmanuel Leblond
1e646e2797 Fix codeblock tag in classes.xml for EditorSettings
(cherry picked from commit 28d7486267)
2017-01-08 12:35:02 +01:00
Rémi Verschelde
4a7d5f7b0e i18n: Sync translations with Weblate
Adds 100% complete Bengali translation.
2017-01-08 12:16:19 +01:00
Rémi Verschelde
a86dae5761 Merge pull request #7141 from Faless/2.1.x-ipv6
Cherry pick IPv6 patches to 2.1.x
2017-01-04 08:38:28 +01:00
Fabio Alessandrelli
7a77fd1cd5 Expose HTTP classes' set_ip_type to scripting
(cherry picked from commit d194e1c48e)
2017-01-04 00:46:33 +01:00
Fabio Alessandrelli
ac9f0aea1a Remove old unused AI_V4MAPPED flag to getaddrinfo
(cherry picked from commit de23ce11b5)
2017-01-04 00:46:33 +01:00
Fabio Alessandrelli
3bb1709fd7 Separate hostname resolve cache based on ip_type
(cherry picked from commit c1c1ec690e)
2017-01-04 00:46:33 +01:00
Fabio Alessandrelli
00fdcf3cd0 IP_Address now handle IPv4 and IPv6 transparently
IP_Address changes:
- Converts to and from String transparently while handling IPv4 as IPv6
  mapped (::ffff:[IP]) address internally.
- Completely remove AddrType enum.
- Setting/Getting of ip array is now only possible through dedicated functions
  (ie. set_ipv4, get_ipv4, set_ipv6, get_ipv6)
- Add function to know if the address is a valid IPv4 (for IP implementation and enet)

(cherry picked from commit 1aff508dd9)
2017-01-04 00:46:33 +01:00
Fabio Alessandrelli
7ef71b9013 Allow setting ip_type for TCP/UDP and HTTP classes
(cherry picked from commit a77a0118f6)
2017-01-04 00:46:33 +01:00
Fabio Alessandrelli
e8a6cbc897 Migrate int.IP_TYPE_ constants to IP.TYPE_
(cherry picked from commit c18c5013f8)
2017-01-04 00:46:32 +01:00
Fabio Alessandrelli
47ae6c6507 Move V6ONLY flag selection inside helpers
(cherry picked from commit 4d90a4fcd5)
2017-01-04 00:46:32 +01:00
Fabio Alessandrelli
5e79ac72b7 Automatically map IPv4 address to IPv6 when needed
(cherry picked from commit 9200da58e4)
2017-01-04 00:46:32 +01:00
Fabio Alessandrelli
a46a643f90 Use an instance variable for ip_type in raw sockets
PacketPeerUDP/StreamPeerTCP/TCP_Server now uses an instance variable
to store the selected ip_type (IPv4/IPv6/ANY, where ANY = dual stack).
All calls to resolve addresses, sending/receving data, connecting/listening
will use that socket type.

(cherry picked from commit 95bdd97768)
2017-01-04 00:46:32 +01:00
Fabio Alessandrelli
c030e602e5 Properly handle tcp connection failure
(cherry picked from commit 4f07b595a1)
2017-01-04 00:46:32 +01:00
Fabio Alessandrelli
19b31297ec Fix _set_ip_addr_port not setting the address.
(cherry picked from commit cdc1ca0f13)
2017-01-04 00:46:32 +01:00
Fabio Alessandrelli
4635671de5 Fix getaddrinfo failing on android
(cherry picked from commit 311f1f165b)
2017-01-04 00:46:32 +01:00
Rémi Verschelde
8f23be8752 Merge pull request #7344 from RandomShaper/fix-uniform-reuse-2.1
Fix error when fragment and lighting code share an uniform
2016-12-23 15:57:31 +01:00
Pedro J. Estébanez
490f51a202 Fix error when fragment and lighting code share an uniform 2016-12-21 02:24:47 +01:00
Fabio Alessandrelli
1a7f14b206 [IPv6] Fix windows build script (link to ws2_32) 2016-12-11 18:12:46 +01:00
Fabio Alessandrelli
e1dfaaf786 Define IPV6_V6ONLY flag if not defined on windows (old mingw versions)
(cherry picked from commit bdc7ca84ca)
2016-12-11 18:12:46 +01:00
Fabio Alessandrelli
3f6fe2f3f1 Update docs to IPv6
(cherry picked from commit 7f42da0330)
2016-12-11 18:12:46 +01:00
Fabio Alessandrelli
2fff8e8cde Set proper ip_type default for listen() and resolve_hostname()
(cherry picked from commit 7eef15b734)
2016-12-11 18:12:46 +01:00
Fabio Alessandrelli
754e9aa60a TCP/UDP Listen sockets can now be set to IPv6 only
(cherry picked from commit eb27e993f0)
2016-12-11 18:12:46 +01:00
Fabio Alessandrelli
a2048efd72 Add optional IP type param in TCP/UDP connect/set_send_address
(cherry picked from commit 2f1c859272)
2016-12-11 18:12:45 +01:00
Fabio Alessandrelli
70a6791150 Fix windows debugger connection problems.
Unify network socket creation between platform.
Ensure IPV6_V6ONLY flag is not set on sockets (allow IPv4 connection in IPv6 socket, dual-stack).

(cherry picked from commit 812908e236)
2016-12-11 18:12:45 +01:00
Fabio Alessandrelli
6e0de0cce8 TCPServer listen now default to IP type ANY (v6 socket with v4 support)
(cherry picked from commit ee69bd81cf)
2016-12-11 18:12:45 +01:00
Fabio Alessandrelli
04def2161e Fix PacketPeerUDP get_packet_port()
Properly convert port field from network to system ordering on incoming packets.

(cherry picked from commit 25e29972a9)
2016-12-11 18:12:45 +01:00
Fabio Alessandrelli
b3443fd848 Pass correct address size (ipv4,ipv6) to socket connect, bind, sendto
The address size passed to network system calls now reflects the the actual IP type (v4 or v6).
Fix Windows and OSX ipv6 sockets

(cherry picked from commit 80e911647c)
2016-12-11 12:35:06 +01:00
Ariel Manzur
5546929712 added implementation of is_valid_ip_address()
(cherry picked from commit a3131a6b5b)
2016-12-11 12:35:06 +01:00
Ariel Manzur
d8b0070b8c added windows support for ipv6, cleaned up unix code
(cherry picked from commit 672225b710)
2016-12-11 12:35:06 +01:00
Ariel Manzur
904285f4b4 address type for http client
(cherry picked from commit 1c2ac490cf)
2016-12-11 12:35:06 +01:00
Ariel Manzur
53fea7f196 fixed some byte order and parsing problems
(cherry picked from commit 1d45f35a4a)
2016-12-11 12:35:06 +01:00
Ariel Manzur
fd1022fd29 adding ipv6
(cherry picked from commit 887a897c02)
2016-12-11 12:35:06 +01:00
Rémi Verschelde
24a440a34f Merge pull request #7239 from eska014/2.1-asmjs
Backport web export changes for 2.1
2016-12-08 07:46:37 +01:00
eska
5ede1a1226 Emit asm.js code into a dedicated file for asm.js export
This helps prevent browser lockups during start-up at the cost of having
to distribute an extra file.
2016-12-04 02:52:14 +01:00
eska
17422f1f86 Add fullscreen features in web export
- Implement fullscreen control, get_window_size, get_screen_size
 - Fix fullscreen resolution
2016-12-04 02:52:14 +01:00
eska
49e22aa83f Fix some mouse bugs in WebAssembly/asm.js
- Emit mouse wheel release events
 - Set button masks, fixes #5092
2016-12-03 15:33:59 +01:00
eska
6d86a63648 OS additions and fixes for WebAssembly/asm.js
- Implement alert, shell_open, set_window_title
 - Add locale lookup, fixes #2477
 - Print without color control sequences
 - Move get_executable_path implementation to OS_JavaScript
2016-12-03 15:33:32 +01:00
Rémi Verschelde
a3582fa3cb png: Allow building shared freetype with bundled libpng
This was the behaviour when building Godot 2.1, which allows to build against
Ubuntu 12.04 and its freetype that links old libpng12, while still bundling
libpng16.

(cherry picked from commit 4965ddfaa1)
2016-11-19 14:09:12 +01:00
Rémi Verschelde
326978dcce Revert "libpng: Fix erroneously linking against libpng12 on old distros"
This reverts commits 5fa1bb331a
and ec4be71fad.

Looks like Debian/Ubuntu are not even shipping libpng16 nowadays in their
stable releases, we'll have to go back to statically linking our own
libpng16 to wait for them to stop being 5 years behind everybody.

(cherry picked from commit c32766a482)
2016-11-19 13:40:53 +01:00
Rémi Verschelde
76233a3022 libpng: Same fix as previous commit for server platform
(cherry picked from commit ec4be71fad)
2016-11-19 13:26:30 +01:00
Andreas Haas
ed2c369785 Fix Script Editor drawing over Dialogs.
Resets the z-index when focus is lost and the completion is shown.

Fixes #6769

(cherry picked from commit f73b501d6f)
2016-11-19 13:04:02 +01:00
Rémi Verschelde
220bcbf7c0 libpng: Fix erroneously linking against libpng12 on old distros
This bit us for 2.1.1 binaries built on Ubuntu 12.04 LTS where
libpng.pc apparently prioritizes libpng12.

(cherry picked from commit 5fa1bb331a)
2016-11-19 13:00:17 +01:00
Rémi Verschelde
3e2247ca53 Release 2.1.1-stable 2016-11-15 09:14:21 +01:00
Rémi Verschelde
bf3cf5505e classref: Sync with current source 2016-11-15 09:14:02 +01:00
Rémi Verschelde
bcc887bbe5 i18n: Sync translations with Weblate and update template 2016-11-15 09:10:37 +01:00
Rémi Verschelde
9b32df9cab i18n: Remove translations below 20% completion
They are of course kept in master to be synced in Weblate.
2016-11-15 09:07:53 +01:00
Ben Hickling
601f056b6f Added snapping to 3D path handles to bring it in line with its 2D counterpart
(cherry picked from commit 4d1acab79b)
2016-11-15 08:44:53 +01:00
volzhs
14b46c4263 Check entered and trimmed path when create, import, install project
(cherry picked from commit 2d9e89ea2a)
2016-11-15 08:44:53 +01:00
khairul169
8a813e2a1e Uncomment debug properties of HTTP Request
(cherry picked from commit 6a7aebdf6c)
2016-11-15 08:44:53 +01:00
volzhs
679e9f413c Fix crash when select target path on import 3d scene window
(cherry picked from commit b0cf201ea3)
2016-11-15 08:44:53 +01:00
Pedro J. Estébanez
19ce11b908 Update/fix Android build
Fix wrong path for 32-bit Windows, which fixes #7084
Exclude 32-bit Windows from multi-threaded linking because it's not supported by the NDK
Remove 32-bit Linux as there is no NDK variant for it
(cherry picked from commit 5a26459c06)
2016-11-15 08:44:53 +01:00
eska
28944e95e7 Clarify a NULL comparison
'TreeItem::get_children()' does not return the child count, but rather
a pointer to the children.

This comparison caused an error during WebAssembly builds using the
LLVM backend path.

(cherry picked from commit 31f929caa2)
2016-11-15 08:37:53 +01:00
volzhs
2d6dabc68e Prevent to select children if selection lock or instanced scene
Fix #7086

(cherry picked from commit c3f4d676c0)
2016-11-15 08:37:48 +01:00
volzhs
9219ac7e44 Fix resetting to default value in EditorSettings
(cherry picked from commit 70cce6152d)
2016-11-15 08:36:53 +01:00
Elia Argentieri
e3dc319f78 Make the step property useful for sliders as described in #5773
(cherry picked from commit 0955371447)
2016-11-15 08:36:18 +01:00
Pedro J. Estébanez
221346521c Make Android export quicker (especially on Windows)
(cherry picked from commit 56721e5d9d)
2016-11-15 08:35:15 +01:00
Pawel Kowal
f1c2d70f1a Export immediately if only one device present
(cherry picked from commit 938f9388dd)
2016-11-15 08:35:01 +01:00
volzhs
3e127ce3fd Fix Directory.dir_exist/get_current_dir for 'res://' on Android
Fix #7014

(cherry picked from commit 8d454ed9a7)
2016-11-15 08:34:51 +01:00
ISylvox
0413d85add vsnc --> vsync
(cherry picked from commit b5c383fd61)
2016-11-15 08:34:43 +01:00
volzhs
7d09222b37 Set project name as directory name instead of '.'
(cherry picked from commit 571f33f863)
2016-11-15 08:34:38 +01:00
volzhs
dd8b87f58e Select newly created or imported project automatically
(cherry picked from commit b8f80e9450)
2016-11-15 08:34:32 +01:00
volzhs
36a4c54593 Fix Label valign position
Fix #7055

(cherry picked from commit c0e87f2a24)
2016-11-15 08:34:26 +01:00
SPTelur
51fe9fc132 Some missing License notice has been added
(cherry picked from commit df737ebb46)
2016-11-15 08:34:16 +01:00
Paulb23
9e1e5daddf Caret blink will no longer cause redraw without focus, issue 6167
(cherry picked from commit 7b036a94bf)
2016-11-15 08:34:01 +01:00
DTV96Calibre
bc8dabf3d2 Fixed minor typo
(cherry picked from commit 37098419c5)
2016-11-15 08:30:35 +01:00
Pedro J. Estébanez
fada9d7a8e Clean/fix triangulation internals
Drop unused variable
Remove commented-out code
Fix leak by using Vector instead of raw memory

(cherry picked from commit 0e1972aa51)
2016-11-15 08:30:09 +01:00
volzhs
82b458f160 Fix updating value of SpinBox with prefix
(cherry picked from commit 80b6507071)
2016-11-15 08:30:02 +01:00
volzhs
64f38490df Prevent to make UndoRedo for duplicate if no selected node
(cherry picked from commit d82928eb49)
2016-11-15 08:29:56 +01:00
ScotFlux
c282ac8ec7 fix a tiny typo
(cherry picked from commit 8639d6e806)
2016-11-15 08:29:30 +01:00
Rémi Verschelde
210618c5e2 Rewrite the README to be more descriptive
(cherry picked from commit ab9fa604d1)
2016-11-15 08:29:23 +01:00
volzhs
2b00fdc679 Fix wrong number for ERR_* on comment
(cherry picked from commit 42f2380190)
2016-11-15 08:29:09 +01:00
Tim Roes
d7ec768805 Fix typos and missing newlines in --help
(cherry picked from commit c34aa331ec)
2016-11-15 08:28:58 +01:00
Keetz
86c6aabf27 Fix scene tree drag & drop places node as child (#6912)
(cherry picked from commit 2afcbc4b1f)
2016-11-15 08:28:52 +01:00
Saracen
e5f210693c Fixed flag for importing animation and skipping value tracks.
(cherry picked from commit 0063471edd)
2016-11-15 08:28:26 +01:00
Ignacio Etcheverry
7e3360ae01 Keep groups when replacing nodes
(cherry picked from commit 305956bf70)
2016-11-15 08:28:11 +01:00
Ariel Manzur
67f65f6639 memory ops implemented as OS functions by default 2016-11-08 19:04:56 -03:00
Ariel Manzur
dbca4ee3fe adding get_stored_values method
changed order name
2016-11-08 18:14:10 -03:00
Rémi Verschelde
cd828bd5fc server: Allow building against system libraries
(cherry picked from commit 5e360fe178)
2016-11-03 22:55:24 +01:00
Rémi Verschelde
da4a870bc4 opus: Move public headers to match system install
(cherry picked from commit 611a94e3a6)
2016-11-03 21:22:56 +01:00
Rémi Verschelde
ce54b6ea8b scons: Reorder options for clarity
Also prefix all thirdparty-related toggles with `builtin`.

(cherry picked from commit cc95d4448c)
2016-11-03 08:41:10 +01:00
Rémi Verschelde
5ee9a9962f libpng: Update to upstream 1.6.26
(cherry picked from commit 7504a85e5a)
2016-11-03 08:34:19 +01:00
Pedro J. Estébanez
f629b1fd3e Improve Android build (Clang + tidyness)
(cherry picked from commit b18ff942be)
2016-11-02 22:34:17 +01:00
Rémi Verschelde
eaf803f71e style: Various other PEP8 fixes in Python files
Done with `autopep8 --select=E7`, fixes:

- E701 - Put colon-separated compound statement on separate lines.
- E702 - Put semicolon-separated compound statement on separate lines.
- E703 - Put semicolon-separated compound statement on separate lines.
- E711 - Fix comparison with None.
- E712 - Fix (trivial case of) comparison with boolean.
- E713 - Fix (trivial case of) non-membership check.
- E721 - Fix various deprecated code (via lib2to3).
2016-11-02 22:30:34 +01:00
Rémi Verschelde
a7389217f8 style: Fix PEP8 blank lines issues in Python files
Done with `autopep8 --select=E3,W3`, fixes:

- E301 - Add missing blank line.
- E302 - Add missing 2 blank lines.
- E303 - Remove extra blank lines.
- E304 - Remove blank line following function decorator.
- E309 - Add missing blank line.
- W391 - Remove trailing blank lines.
2016-11-02 22:29:36 +01:00
Rémi Verschelde
e259bf8bbb style: Fix PEP8 whitespace issues in Python files
Done with `autopep8 --select=E2,W2`, fixes:

- E201 - Remove extraneous whitespace.
- E202 - Remove extraneous whitespace.
- E203 - Remove extraneous whitespace.
- E211 - Remove extraneous whitespace.
- E221 - Fix extraneous whitespace around keywords.
- E222 - Fix extraneous whitespace around keywords.
- E223 - Fix extraneous whitespace around keywords.
- E224 - Remove extraneous whitespace around operator.
- E225 - Fix missing whitespace around operator.
- E226 - Fix missing whitespace around operator.
- E227 - Fix missing whitespace around operator.
- E228 - Fix missing whitespace around operator.
- E231 - Add missing whitespace.
- E231 - Fix various deprecated code (via lib2to3).
- E241 - Fix extraneous whitespace around keywords.
- E242 - Remove extraneous whitespace around operator.
- E251 - Remove whitespace around parameter '=' sign.
- E261 - Fix spacing after comment hash.
- E262 - Fix spacing after comment hash.
- E265 - Format block comments.
- E271 - Fix extraneous whitespace around keywords.
- E272 - Fix extraneous whitespace around keywords.
- E273 - Fix extraneous whitespace around keywords.
- E274 - Fix extraneous whitespace around keywords.
- W291 - Remove trailing whitespace.
- W293 - Remove trailing whitespace.
2016-11-02 22:28:28 +01:00
Rémi Verschelde
561c1f17a1 style: Start applying PEP8 to Python files, indentation issues
Done with `autopep8 --select=E1`, fixes:

- E101 - Reindent all lines.
- E112 - Fix under-indented comments.
- E113 - Fix over-indented comments.
- E115 - Fix under-indented comments.
- E116 - Fix over-indented comments.
- E121 - Fix a badly indented line.
- E122 - Fix a badly indented line.
- E123 - Fix a badly indented line.
- E124 - Fix a badly indented line.
- E125 - Fix indentation undistinguish from the next logical line.
- E126 - Fix a badly indented line.
- E127 - Fix a badly indented line.
- E128 - Fix a badly indented line.
- E129 - Fix a badly indented line.
2016-11-02 22:26:55 +01:00
volzhs
7c92b401f1 Fix to fit stylebox with ItemList
(cherry picked from commit 4c9b00b508)
2016-11-02 22:18:34 +01:00
m4nu3lf
d44e6ea268 Fixed Mix nodes in Animation Tree Player
(cherry picked from commit 40ba6d328b)
2016-11-02 22:18:28 +01:00
Rémi Verschelde
1185da656f Merge pull request #6988 from RandomShaper/2.1
Fix shader tokenizer/compiler reporting wrong error location (2.1)
2016-11-02 22:10:00 +01:00
Rémi Verschelde
c78aef5812 Fix usage of 3.0 naming API in 1038c1f8 2016-10-31 08:39:45 +01:00
volzhs
91af714d39 Fix memory leak with drag & drop on 2D viewport
(cherry picked from commit a7d492eb53)
2016-10-31 07:55:23 +01:00
Andreas Haas
5033fc92f4 Ability to drag script files from Filesystem dock to SceneTree dock.
Allows to attach scripts by dragging them onto the target Node.

(cherry picked from commit a3944e66da)
2016-10-31 07:55:03 +01:00
volzhs
1038c1f856 Improve drag and drop on 2D viewport
(cherry picked from commit eed9179ea3)
2016-10-31 07:53:31 +01:00
Rémi Verschelde
8087be05c7 scons: msvc_is_detected not available in 2.1 2016-10-31 07:52:40 +01:00
Rémi Verschelde
a20da0c048 classref: Sync with current sources 2016-10-31 00:15:54 +01:00
volzhs
d67bbd183e Fix p_index out of size error when closing script
(cherry picked from commit 707185d9d8)
2016-10-31 00:07:56 +01:00
volzhs
647b287a1e Fix Accept/ConfirmationDialog UI broken
(cherry picked from commit 8d5644c4b2)
2016-10-31 00:07:47 +01:00
volzhs
91df1ebff6 Revert "Place child control under label in AcceptDialog."
This reverts commit 3ef2722904.

(cherry picked from commit 3f15a65307)
2016-10-31 00:07:40 +01:00
Rémi Verschelde
62d1e39113 scons: Move lib splitting method to methods.py
Apparently it might still be necessary for some console ports.

(cherry picked from commit e34a5324c8)
2016-10-31 00:07:29 +01:00
Pedro J. Estébanez
b492dd78bd Adopt simpler strategy for big libs on Windows
(cherry picked from commit 51ad1c1668)
2016-10-31 00:05:42 +01:00
rdb
a27aee241c Add "Never" underline mode to LinkButton
(cherry picked from commit d517bc908f)
2016-10-31 00:05:32 +01:00
Damon
e3be51f87c Fix locale for macOS-style locales
(cherry picked from commit 1e7f078ce9)
2016-10-31 00:04:39 +01:00
Damon Myers
68b6b50d28 Change set_locale to fallback to the global language (#6910)
(cherry picked from commit 470ead74db)
2016-10-31 00:04:26 +01:00
volzhs
06c47e6f8a Remove dead code in FileSystemDock
(cherry picked from commit 9605a1d0da)
2016-10-31 00:02:12 +01:00
volzhs
e56961f58b Fix comparison bug with InputEvent
(cherry picked from commit b76a0ca40c)
2016-10-31 00:02:04 +01:00
Błażej Szczygieł
b0013f32bf "CCFLAGS" are for C and C++ compiler
(cherry picked from commit ace18d28d2)
2016-10-31 00:01:41 +01:00
Henrique Lacreta Alves
58daf901f9 Prevent unwanted script editor input on game crash
Fixes #6530.
(cherry picked from commit 853d1ce9f3)
2016-10-31 00:01:11 +01:00
Pedro J. Estébanez
887b1de1db Add/expose VisualServer::get_default_clear_color()
(cherry picked from commit 753ba67d65)
2016-10-31 00:00:55 +01:00
yg2f
caf42f77d2 Fixes #6487, GDscript compiler ignores OPCODE_LINE and OPCODE_BREAKPOINT in Release mode
When godot is in release mode, GDscript compiler does not generate
bytecodes for OPCODE_LINE and OPCODE_BREAKPOINT anymore.

This optimizes GDscript execution speed when the script contains a lot
of comments in blocs executed in loops.

Fixes #6487

(cherry picked from commit 217e09c79d)
2016-10-31 00:00:46 +01:00
Karol Walasek
9f9d1eed7b Added general notes on RayCast[2D] updating behaviour and force_raycast_update()
(cherry picked from commit 8d57640d37)
2016-10-31 00:00:34 +01:00
Karol Walasek
0af331d1c0 Added force_raycast_update GDScript method for RayCast[2D]
(cherry picked from commit 7494a8c3c6)
2016-10-31 00:00:23 +01:00
George Marques
7a17d72e84 Fix extraneous NULL character on HTML export
Fix #2801

(cherry picked from commit 604ddd691c)
2016-10-30 23:58:41 +01:00
George Marques
52bf8bd168 Fix the hiding of mouse cursor before interaction
Fix part of #6633

(cherry picked from commit 414d58e6c0)
2016-10-30 23:58:32 +01:00
George Marques
f3b42e049d Fix output binary paths for VS project generation
(cherry picked from commit c8093678a0)
2016-10-30 23:57:54 +01:00
Pedro J. Estébanez
a130520a7c Fix shader tokenizer/compiler reporting wrong error location
Raname shader tokenizer methods for clarity
2016-10-30 22:09:23 +01:00
Błażej Szczygieł
85a7105345 SCons: Use colored output if available, change "colored"->"verbose"
(cherry picked from commit 2bf4553fe0)
2016-10-30 14:51:34 +01:00
Błażej Szczygieł
dcd4b80c13 Disable asserts in release mode
(cherry picked from commit 639ea563e0)
2016-10-30 14:51:34 +01:00
Rémi Verschelde
5a49e45d21 SCsub: Add python shebang as a hint for syntax highlighting
Also switch existing shebangs to "better" /usr/bin/env python.

(cherry picked from commit fc8ccd5b8c)
2016-10-30 14:51:34 +01:00
Błażej Szczygieł
7143401e25 Theora: Don't compile unnecessary files, rename "x86_opt_*"
(cherry picked from commit 4ffa8f224d)
2016-10-30 14:51:34 +01:00
Rémi Verschelde
f4414e3e03 png: Try to fix neon issue on iphone armv7
(cherry picked from commit e57042e8a9)
2016-10-30 14:51:34 +01:00
Rémi Verschelde
aa1367595e drivers: Refactor SCsub and drop redundant env_drivers clone
The reordering of the SConscript includes allows to ensure that
stuff like the builtin zlib headers will be available for libpng.

Also moved glew back into global env, otherwise windows seems
not to find it... Kind of shooting in the dark with this multi-env
setup.

(cherry picked from commit 248bc9159c)
2016-10-30 14:51:34 +01:00
Rémi Verschelde
d96842b80e freetype: Make it a module and split thirdparty library
Comment out the weird workaround for building on Windows at it might
not be needed anymore. Testing needed to confirm.

(cherry picked from commit edbc0c0d0b)
2016-10-30 14:51:33 +01:00
Rémi Verschelde
8bf3bc3449 chibi: Move to a module
(cherry picked from commit e6dc51a0f7)
2016-10-30 14:51:33 +01:00
Rémi Verschelde
f1bd2f6f56 zlib: Split thirdparty files, simplify scons option
(cherry picked from commit cbf52606f4)
2016-10-30 14:51:33 +01:00
Rémi Verschelde
e04ec9565b glew: Split thirdparty files and isolate env
Not fully happy about the way this one interacts with the various
platforms. Maybe the platform_config.h should be generated by the
SCsub instead of passing a define just to know where is the header.

(cherry picked from commit 36738ddda4)
2016-10-30 14:51:33 +01:00
Rémi Verschelde
8263fca121 squish: Update to upstream 1.14
Sources are untouched, tarball from https://sourceforge.net/projects/libsquish

(cherry picked from commit 249836e530)
2016-10-30 14:51:33 +01:00
Rémi Verschelde
1022705707 squish: Move to a module and split thirdparty lib
(cherry picked from commit 8311a78df5)
2016-10-30 14:51:33 +01:00
Rémi Verschelde
4ff4177acc rtaudio: Split thirdparty files
(cherry picked from commit 8981ff8a84)
2016-10-30 14:51:33 +01:00
Rémi Verschelde
c8a97c3678 mpc: Move to a module and split thirdparty libmpcdec
(cherry picked from commit 5c12c9e69b)
2016-10-30 14:51:33 +01:00
Rémi Verschelde
82e8721715 theora: Move to a module and split thirdparty lib
Same rationale as the previous commits.

(cherry picked from commit cfcc8a20e8)
2016-10-30 14:51:32 +01:00
Rémi Verschelde
bfea3f1d9a modules: Clone env in each module
This allows to pass include paths and flags only to a given thirdparty
library, thus preventing conflicts between their files (e.g. between
opus and openssl which both provide modes.h.

This also has the nice effect of making the compilation command smaller
for each module as it no longer related to all other modules, only the
final linking brings them together.

This however requires adding manually the ogg include path in opus
and vorbis when building against the builtin ogg, since it is no longer
in the global env.

Also simplified template 'thirdparty_<module>_sources' to
'thirdparty_sources'.

"Core" modules like cscript, gdscript, gridmap, ik and virtual_script
still use the main env_modules, but it could be changed if need be.

(cherry picked from commit da09c6131b)

Obviously removed the parts about enet and visual_script.
2016-10-30 14:51:32 +01:00
Rémi Verschelde
4cd640f684 openssl: Move to a module and split thirdparty lib
Same rationale as the previous commits.

(cherry picked from commit 422196759f)

Removed the winrt-specific parts.
2016-10-30 14:51:32 +01:00
Rémi Verschelde
995dcb610c ogg/vorbis/opus/speex: Make them modules and unbundle thirdparty libs
Took the opportunity to undo the Godot changed made to the
opus source. The opus module should eventually be built in its
own environment to avoid polluting others with too many include
dirs and defines.

TODO: Fix the platform/ stuff for opus.
(cherry picked from commit d9a291f641)

speex module was only added while cherry-picking, as speex is removed
in the master branch but we don't want to break compatibility in 2.1.x.
Unbundling wasn't done as the module uses the internal speex_free,
so it would require some more work.
2016-10-30 14:51:31 +01:00
Rémi Verschelde
55414bc573 webp: Make it a module and unbundle libwebp thirdparty files
Note that there are two Godot-specific changes made to libwebp
for the javascript/HTML5 platform. They are documented in the
README.md.

(cherry picked from commit ee3cf211c6)
2016-10-30 14:51:30 +01:00
Rémi Verschelde
819ccdd340 dds/etc1/pbm/pvr: Make those modules and split thirdparty files
They are not particularly packaged in Linux distros so we do not
facilitate unbundling via SCons. There could be done if/when there
is interest.

Also s/pnm/pbm/, long-lived typo :)

(cherry picked from commit b1e8889d96)
2016-10-30 14:51:30 +01:00
Rémi Verschelde
ea1e180e4a jpg: Make it a module and split jpgd thirdparty files
Similar rationale as in previous commit.

(cherry picked from commit 16ba665db6)
2016-10-30 14:51:30 +01:00
Rémi Verschelde
575e986bde png: Split library to thirdparty dir and allow unbundling
Uses the new structure agreed upon in #6157, but the thirdparty/ folder
does not behave following a logic similar to that of modules/ yet.

The png driver can't be moved to a module as discussed in #6157, as it's
required by core together with a few other ImageLoader implementations
(see drivers/register_driver_types.cpp:register_core_driver_types())

Dropped the possibility to disable PNG support, it's a core component
of Godot.

(cherry picked from commit 5fef84a135)
2016-10-30 14:51:30 +01:00
Rémi Verschelde
846db09038 Drop nedmalloc which is apparently not used anymore
(cherry picked from commit f63bf12193)
2016-10-30 14:51:30 +01:00
Zher Huei Lee
fae2863a5e Added support for tooltips in ButtonArray. Fixes #6597
(cherry picked from commit 38caa4ef91)
2016-10-30 14:51:30 +01:00
Rémi Verschelde
56b03e7208 Merge pull request #6877 from ranmaru90/2.1
Fixed tiny error in detect.py causing compilation for Android to fail.
2016-10-22 13:03:35 +02:00
Randy Tan Shaoxian
c9d7f77c6f Fixed tiny error in detect.py causing compilation for Android to fail. 2016-10-20 21:17:21 +08:00
Rémi Verschelde
14e45a55d4 Revert "Tween reset/stop/resume/remove for all object properties at once"
This reverts commit 6fc894d652.
It caused a regression, cf. #6863.
2016-10-18 21:43:46 +02:00
Juan Linietsky
7d25d20861 Added a generic AStar implementation to Godot.
It's pretty fast, use it for games where Navigation does not cut it.

(cherry picked from commit 827a9aa829)
2016-10-18 18:35:44 +02:00
Andreas Haas
e88a540b91 osx: Support gamepad input.
Fixes #3881

Vibration support is not optimal yet as it doesn't try to emulate the "weak" and "strong" motor strength,
but just takes the parameter with the highest value for the vibration gain.

(cherry picked from commit 8c886b9d7a)
2016-10-18 18:34:16 +02:00
Rémi Verschelde
2287bac8f7 classref: Sync with current source 2016-10-17 21:07:01 +02:00
volzhs
00b0f3dfde Fix crash when using Directory.dir_exists(path) on Android
(cherry picked from commit 4a57821349)
2016-10-17 20:50:57 +02:00
Andreas Haas
64b083b496 Allow whitespace in Gamepad mappings.
Previously, mappings that contained whitespace (most likely after a comma seperator) would not parse
correctly.
Consider the following mapping as an example:

"_test_guid_, test controller, a:b0, b:b1, leftx:a0 ,"

(cherry picked from commit fa502b7ccc)
2016-10-17 20:50:43 +02:00
volzhs
9b71cae50f Add option for root node name on Import 3D scene window
(cherry picked from commit dd04ac7ba9)
2016-10-17 20:50:20 +02:00
Karol Walasek
8a8ace8fa0 Fixed Particle2D docs - radians to degrees for some params
(cherry picked from commit 5687fa4709)
2016-10-17 20:49:52 +02:00
Pedro J. Estébanez
2261c65f19 Adapt overlooked instances of zero-based column numbers
(cherry picked from commit 1b3dcac281)
2016-10-17 20:49:28 +02:00
Andreas Haas
a418304def Only show AnimationEditor automatically when an Animplayer is selected.
Previous behaviour was to show it when an AnimationPlayer has been detected in the scene, now you actually have to select it.
Fixes #6213

(cherry picked from commit 86fd40b06c)
2016-10-17 20:49:18 +02:00
Fabio Alessandrelli
ea48675ffa Properly handle absolute paths in Globals::localize_path
This give a proper fix for #4280 - #3106 , allowing absolute paths
that starts from the file system, not the resource folder

(cherry picked from commit 2f2cea070e)
2016-10-17 20:49:12 +02:00
Fabio Alessandrelli
d5ee98bb2c Revert "Add warning when (pre)loading paths with leading / (#4280 - #3106)"
Also closes: #6801

This reverts commit e59820ac94.

(cherry picked from commit 11349a786b)
2016-10-17 20:48:52 +02:00
volzhs
728ac94313 Add "button_selected" signal to ButtonGroup
(cherry picked from commit 870ed6f2fa)
2016-10-17 20:48:36 +02:00
Zher Huei Lee
a8502ae6f6 Fixes for ButtonArray
Fixed hover sometimes not resetting when mouse leaves widget.
Fixed text position not taking into account stylebox's content margins.

(cherry picked from commit f5830e0973)
2016-10-17 20:48:25 +02:00
Răzvan Cosmin Rădulescu
04255541a0 Fixes hash float negative 0 problem
Before this was giving an error:

var a = {Vector2(1, 0): 5, Vector2(-1, 0): 7}
    print(a)
    print(a[Vector2(1, 0)])
    print(a[-Vector2(1, 0)])

This simple commit fixes the issue.

(cherry picked from commit 9ad0850301)
2016-10-17 20:48:15 +02:00
Mateusz Adamczyk
17edff2f84 Possibility to write node path by hand in exported NodePath variable (#3486)
(cherry picked from commit cf4f3815b3)
2016-10-17 20:48:10 +02:00
Anthony Fieroni
b4edaa892d Correct OS architecture detection
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
(cherry picked from commit f87e32696d)
2016-10-17 20:48:05 +02:00
volzhs
81bc271619 Replace a node with saved branch scene instance
(cherry picked from commit cc33c528eb)
2016-10-17 20:47:49 +02:00
Andreas Haas
5f540a17cc Sprite: Fix inspector not showing changes on "frame" property.
Fixes #6562

(cherry picked from commit 9d67895c7c)
2016-10-17 20:47:27 +02:00
Andreas Haas
4b6809a2b3 Refresh TextureRegionEditor when region has been changed externally.
Now the TextureRegionEditor updates when you change the region_rect either via the inspector or via
undo/redo.

Fixes #6772

(cherry picked from commit 094073e4b2)
2016-10-17 20:47:14 +02:00
Pawel Kowal
280728c0c7 New load icon, removed unused open icon
(cherry picked from commit ed1e71a77e)
2016-10-17 20:46:34 +02:00
Pawel Kowal
35cdb1a49b Fix #5959, contrasting texture for toggled button
(cherry picked from commit d3a8087659)
2016-10-17 20:46:10 +02:00
Pedro J. Estébanez
3df8f79c9f Allow step for integer properties
Small readability improvement

(cherry picked from commit 7b293aa4d4)
2016-10-17 20:44:54 +02:00
Pedro J. Estébanez
99d82f3033 Make text column numbers one-based
Make one-based the column number on the code editor

Make one-based the column number for GDScript error messages

Make one-based the column number for shader code error messages

(cherry picked from commit 2f80965845)
2016-10-17 20:44:47 +02:00
Anthony Fieroni
f250c0cf50 Button focus hovering
Signed-off-by: Anthony Fieroni bvbfan@abv.bg
(cherry picked from commit 6d21fd42d3)
2016-10-17 20:43:36 +02:00
Ignacio Etcheverry
55a5631986 Bindings: Fix missing default value
(cherry picked from commit 068b58b3ce)
2016-10-17 20:43:25 +02:00
George Marques
8cb09bf9d0 Fix Android build detection on Windows
(cherry picked from commit 4bdbafabce)
2016-10-17 20:43:03 +02:00
Mateusz Adamczyk
58e2652f94 Place child control under label in AcceptDialog.
Fixes #6199.

(cherry picked from commit 3ef2722904)
2016-10-17 20:42:51 +02:00
Rémi Verschelde
3f941faf4d i18n: Sync translations from Weblate and merge with current code 2016-10-09 18:23:26 +02:00
Rémi Verschelde
b3bf3c392a i18n: Fix string that broke msgmerge
(cherry picked from commit 2fb5a00305)
2016-10-09 18:21:59 +02:00
Rémi Verschelde
c757787fed classref: Sync with current 2.1 branch 2016-10-09 17:50:09 +02:00
J08nY
1ae1deabfa editor_node: add an option to stop the update spinner from spinning, fixes #6653
(cherry picked from commit 4527fbcfa1)
2016-10-09 17:41:04 +02:00
Pedro J. Estébanez
22680a30f1 Fix reparent undo not renaming back
(cherry picked from commit 88a32c11f1)
2016-10-09 17:40:49 +02:00
Mateusz Adamczyk
ce1138cb02 Added simple check to viewport, if matrix32 is invesile (https://github.com/godotengine/godot/issues/6296).
(cherry picked from commit 8671836b76)
2016-10-09 17:40:37 +02:00
Bojidar Marinov
a139c7afe6 Attempt to fix travis builds for android
Using travis_wait command
(cherry picked from commit f73f554cc0)
2016-10-09 17:40:25 +02:00
Fabio Alessandrelli
e51cd3d454 Throw an error when exporting a resource class
"export var tex = Texture"
will now throw an error to avoid crashing the editor:
"Exported constant not a type or resource"

Fixes #6719 . Closes #6729

(cherry picked from commit ee7df2c89a)
2016-10-09 17:40:19 +02:00
Andreas Haas
a7d6894a9f Project manager: grab focus on ok button after path selection.
Slight usability improvement: grabs focus on the Import/Create button after engine.cfg/path selection.
So then I can just press enter to create the project ^^

(cherry picked from commit 36d2dd5318)
2016-10-09 17:40:10 +02:00
Răzvan Cosmin Rădulescu
6775cce469 fixes #6695 - MultiNodeEdit edit path in exported NodePath
(cherry picked from commit ced8fb4806)
2016-10-09 17:40:03 +02:00
Andreas Haas
9e20b39b3d Fix code completion drawing under other gui elements.
Raises the z-index of the Script editor when the completion is shown.

fixes #1257
fixes #6690

(cherry picked from commit 6dfa405eac)
2016-10-09 17:39:56 +02:00
Andreas Haas
0462bf01a2 Prevent crash on focus change when no valid next control has been found.
Fixes the crash discussed in #6714.

(cherry picked from commit 8dd026e4f9)
2016-10-09 17:39:39 +02:00
Ariel Manzur
cf427eeb7a bind method canvas_item_set_sort_children_by_y
(cherry picked from commit 1f9e16119f)
2016-10-09 17:39:17 +02:00
Adham Zahran
cd03f8cce2 fix #6012 exposed setters and getters of Camera H/V offset to GDScript
(cherry picked from commit cbb0ea315b)
2016-10-09 17:39:06 +02:00
Fabio Alessandrelli
d0ff75c91c Add shortcut to reset cursor position in 3D Editor ( #166 )
The shortcut will focus the origin after you moved around with shift + mouse3.
The default shortcut is the letter "O", like "F" for focus.
This can be customized in the editor shortcuts menu.

Closes #166

(cherry picked from commit 63abe3dcd0)
2016-10-09 17:39:00 +02:00
Pedro J. Estébanez
82dfaf7af6 Fix compile flags not getting to the Android build
(cherry picked from commit 7f51bb7b1c)
2016-10-09 17:34:36 +02:00
Pedro J. Estébanez
c0ba08b8d5 Add editor_only param to Light2D
(cherry picked from commit 34c02fad5a)
2016-10-09 17:34:29 +02:00
Fabio Alessandrelli
ba095b8dcc Add warning when (pre)loading paths with leading / (#4280 - #3106)
(cherry picked from commit e59820ac94)
2016-10-09 17:34:23 +02:00
Andreas Haas
9593863a92 ConnectionDialog: Don't allow connecting to a Node without a script if target method is invalid.
Shows a warning now.
Fixes #6656

(cherry picked from commit 5b7021434f)
2016-10-09 17:34:12 +02:00
Răzvan Cosmin Rădulescu
97ebfddaaf fixes #6331, Variant::can_convert
(cherry picked from commit f2af5ab949)
2016-10-09 17:34:00 +02:00
J08nY
342b1408d5 light: respect editor_only setting in release build and dont show the light
(cherry picked from commit af35130b50)
2016-10-09 17:33:54 +02:00
Fabio Alessandrelli
359b5f3b25 Expose more 2D/3D physics options in project settings
(cherry picked from commit 1d09c27ba4)
2016-10-09 17:33:47 +02:00
J08nY
5b942f056a Vector3: added angle_to(Vector3 other)
(cherry picked from commit deb36b44d1)
2016-10-09 17:33:36 +02:00
J08nY
44ba542de6 Vector3: format properly, fix indents
(cherry picked from commit f468cfc379)
2016-10-09 17:33:30 +02:00
mookiexl
f63b338e0f Limit directional shadow draw distance, fixes #559, optimization (#1991)
* Shadow fadeout exponent hardcoded for now, should be user configurable.
* optimization - skip shadows outside visible range
(cherry picked from commit 0b12ebba11)
2016-10-09 17:33:20 +02:00
Błażej Szczygieł
13108317ae Fixes in Theora SCsub
- properly pass x86 assembly define to the compiler,
- don't compile unnecessary/encoder files.

(cherry picked from commit 75299cf334)
2016-10-09 17:33:12 +02:00
Pedro J. Estébanez
12d4d65668 Improve debug focus behavior
Fix focusing debugged game on Windows
Add re-focusing editor on continue

(cherry picked from commit 66dac878ac)
2016-10-09 17:29:59 +02:00
Fabio Alessandrelli
56dc7aa568 Properly encode InputEvent of type NONE. Fix #5987
In the editor settings you can disable default editor shortcuts.
When a default shortcut is disabled an InputEvent of type NONE must
be stored in the config file to allow the editor to remember that setting.
variant_parser.cpp was not properly encoding InputEvent of type NONE causing
the "corruption" of the editor settings file.

(cherry picked from commit 941f460384)
2016-10-09 17:29:27 +02:00
J08nY
f315d352ec PCKPacker: moved from tools into core, fixes #4129
(cherry picked from commit b1fba2e013)
2016-10-09 17:28:11 +02:00
J08nY
ef0bcc7e20 PopupMenu: added toggle_item_checked and exposed set_item_tooltip and get_item_tooltip
(cherry picked from commit 6b283ae293)
2016-10-09 17:26:14 +02:00
Karol Walasek
b2a58da321 Filled blanks and normalized documentation on RayCast[2D]
(cherry picked from commit db0a46d7f7)
2016-10-09 17:25:07 +02:00
Pedro J. Estébanez
de13e52b9b Respect texture .flags files on export
(cherry picked from commit 11cbbeb17e)
2016-10-09 17:24:10 +02:00
volzhs
73e7ccabf5 Fix typo for word_wrap
(cherry picked from commit c333659ebc)
2016-10-09 17:23:58 +02:00
volzhs
721599c797 Fix error when using 2 or more slashes on resource path
(cherry picked from commit 0866f49f4e)
2016-10-09 17:23:53 +02:00
Pawel Kowal
ab231cd3fb Fix #6480, area duplicated param
(cherry picked from commit f9a21baa26)
2016-10-09 17:23:43 +02:00
Marc Gilleron
268b3446c6 Windows: prevent huge prints from crashing the engine
(cherry picked from commit 0c09de3ef1)
2016-10-09 17:23:08 +02:00
Pawel Kowal
d7925ca09d LineEdit long indicator, fix #6624
(cherry picked from commit 3edc0a4832)
2016-10-09 17:23:02 +02:00
Błażej Szczygieł
d613952300 Don't crash when video is stopped and played again
(cherry picked from commit 5585bc1c38)
2016-10-09 17:22:54 +02:00
Victor Seiji Hariki
a3c58999e2 Now ignoring remaining collision shapes.
(cherry picked from commit e5edd50d62)
2016-10-09 17:22:48 +02:00
syskrank
4b2243f82e removed confusing "if(true)" statement with empty "else" block
(cherry picked from commit af4b0db1e4)
2016-10-09 17:22:36 +02:00
Pawel Kowal
6fc894d652 Tween reset/stop/resume/remove for all object properties at once
(cherry picked from commit acc242fd6a)
2016-10-09 17:22:16 +02:00
Andreas Haas
5adb75c2e7 Throw error when trying to emit a non-existing signal.
closes #6017

(cherry picked from commit 276087e92d)
2016-10-09 17:22:08 +02:00
Błażej Szczygieł
a827734e03 Don't crash in "_process_hdr()" if "framebuffer.luminance" is empty
If "glFramebufferTexture2D()" fails on old drivers the Vector is empty.
Don't allow to read from empty Vector (NULL pointer).

(cherry picked from commit 7b8fe97888)
2016-10-09 17:22:01 +02:00
Błażej Szczygieł
f4f5855168 Don't crach when OpenGL version is unsupported
(cherry picked from commit ca3b8deb78)
2016-10-09 17:21:48 +02:00
Błażej Szczygieł
f4da1e9ed2 Add compatibility with old OpenGL 2.1 drivers
If ARB_framebuffer_object is not supported, try to fall-back to
EXT_framebuffer_object if present.

In current version of godot, the way framebuffers are used is backward
compatible with the older EXT_framebuffer_object extension.

Fixes #6591
Done with SuperUserNameMan

(cherry picked from commit a27fafb273)
2016-10-09 17:21:41 +02:00
Emmanuel Leblond
a5fe7ffbcd Add CC parameter to allow use of custom C compiler
(cherry picked from commit cfd17de230)
2016-10-09 17:21:33 +02:00
Andreas Haas
02487a4be1 AnimationEditor: zoom using ctrl+wheel
closes #6585

(cherry picked from commit 3cce39c2d3)
2016-10-09 17:21:26 +02:00
romeojulietthotel
228ee4363e Use pkgconfig to locate ALSA libs (#6119)
* This allows building when ALSA libs are in a non-standard location. PKG_CONFIG_PATH alone is not enough as the final link fails. Adding this makes the final link succeed.

* The extra LIBS flag for alsa is not needed so removing.

(cherry picked from commit 94d6757a0d)
2016-10-09 17:21:17 +02:00
yg2f
36b1521cdc expose GeometryInstance.get_aabb() etc fixes #6587
expose ``GeometryInstance.get_aabb();`` to gdscript
expose ``VisualInstance.get_transformed_aabb();`` to gdscript
and debug ``ImmediateGeometry::add_vertex()``;

(cherry picked from commit c1e2358914)
2016-10-09 17:21:07 +02:00
Andreas Haas
d1ad94acf0 x11: Fix event.is_action() for release of modifier keys
The bug was that the release events for these also had the modifier state set, so the event comparison
failed.

Fixes #5901

(cherry picked from commit 6fcf2b2bd8)
2016-10-09 17:20:57 +02:00
George Marques
63b5a80088 Fix crash when disabling main screen plugin
(cherry picked from commit 0ec2b7baea)
2016-10-09 17:20:38 +02:00
Pedro J. Estébanez
45a5769162 Fix manifest generation bug in Android export
(cherry picked from commit 2c9d98bb48)
2016-10-09 17:20:27 +02:00
knd
b9399e93ad removed redundant assign operation in mesh_add_surface: elem_count is reassigned a value before the old one has been used.
(cherry picked from commit 708a028ce8)
2016-10-09 17:20:20 +02:00
Andreas Haas
33223e7a8a Add function to get readable names for joystick events
Closes #6476

(cherry picked from commit e0fcd9331a)
2016-10-09 17:19:57 +02:00
anneomcl
12edde80f2 Fix for #6158. Converting Vector2 to Size2 for scaling functions.
(cherry picked from commit aa5ade834c)
2016-10-09 17:18:54 +02:00
Pawel Kowal
c8299249e4 Show True/False tooltip in property editor for bool values
(cherry picked from commit 623c483eba)
2016-10-09 17:18:43 +02:00
George Marques
1d175be921 Add docs for XMLparser, VideoPlayer and most of Tree
(cherry picked from commit 7cd64c3c8d)
2016-10-09 17:18:36 +02:00
Andreas Haas
94e5c48004 Expose Vector2::clamped() to scripts
Needed this and wondered that there's no built-in function for it.
So I wanted to implement it and saw that it's actually already there, just wasn't bound ^^

(cherry picked from commit c21412fa7e)
2016-10-09 17:18:29 +02:00
Andreas Haas
4084ec4869 Make the choosable default editor layout the same as the actual default one.
Fixes #6266

(cherry picked from commit a2bff72eee)
2016-10-09 17:18:02 +02:00
Andreas Haas
d3b549f2a3 Fix ability to cut/paste text in LineEdit/TextEdit in readonly mode.
Fixes #6466

(cherry picked from commit 9c71e5a9df)
2016-10-09 17:17:54 +02:00
Pawel Kowal
4ca83c635f Add scrolling to Tree control in Drag and Drop mode
(cherry picked from commit 9e5aaa27bc)
2016-10-09 17:17:04 +02:00
Andreas Haas
e788ffff65 Fix input action pressed state not changing for quick joystick movements.
fixes #6488
Also removes a bunch of dead code related to checking if a joystick axis is pressed.

(cherry picked from commit 84783fe77b)
2016-10-09 17:16:19 +02:00
George Marques
6a0d47f34c Add a function to plugin get the main screen parent
- Fix a bug where the main screen button did not disappear when the plugin
  was deactivated.

(cherry picked from commit 98e7c1edba)
2016-10-09 17:12:15 +02:00
Brickcaster
e6d49fb54c Fix for issue #6496
Canged order of NOTIFICATION_DRAW to update scrollbar before scrollbar
is checked to see which list elements to display.

(cherry picked from commit cc7bc07e33)
2016-10-09 17:11:54 +02:00
Rémi Verschelde
eed5d878e8 classref: Sync with current source 2016-09-19 09:08:12 +02:00
Andreas Haas
521b5bd90f Update documentation on joystick vibration.
Added a note that long vibration durations are not recommended because of hardware limitations.
For example, my ps4 controller can only vibrate for ~3s on linux.

(cherry picked from commit cef70a5f8b)
2016-09-18 23:22:14 +02:00
Paulb23
8dca3f3f42 Fix highlight current script when script temputure is disabled
(cherry picked from commit fbd0b6f995)
2016-09-18 23:21:48 +02:00
Błażej Szczygieł
d2aa006ddb Vorbis: Don't compile unnecessary encoder files
(cherry picked from commit 222bc07874)
2016-09-18 23:21:36 +02:00
sanikoyes
ec32c33799 fix ScrollContainer cannot scroll when scroll bar is hidden
(cherry picked from commit b548ef0009)
2016-09-18 23:20:37 +02:00
Paulb23
9b9870ed9f Update current script color on change
(cherry picked from commit a0136838b3)
2016-09-18 23:19:58 +02:00
Juan Linietsky
a72945f4e3 Added constants from types in code completion, somehow this was never added.
Stuff like Label.ALIGN_CENTER or Mesh.PRIMITIVE_TRIANGLES did not complete..

(cherry picked from commit b83350f4b2)
2016-09-18 23:19:04 +02:00
Juan Linietsky
3ff8dea5f9 Fix Viewport.get_mouse_pos() for specific situations, closes #1885
(cherry picked from commit b16f41a10a)
2016-09-18 23:17:07 +02:00
Pawel Kowal
2b43d0a028 ScrollContainer expand children bug fix
(cherry picked from commit 853161a000)
2016-09-18 23:16:33 +02:00
George Marques
ee23649813 Fix the Windows environment in SCons spawn function
Properly fix #2974 as discussed there.

(cherry picked from commit aad87ab1b6)
2016-09-18 23:15:56 +02:00
sanikoyes
75f51aece9 Tween: fix non-repeat interpolate_callback does not delete after call triggered
(cherry picked from commit cccea7e0b4)
2016-09-18 23:15:43 +02:00
Ovnuniarchos
5653ac41f9 Mouse hotspot is not honored.
(cherry picked from commit 8fcd92c38a)
2016-09-18 23:15:32 +02:00
Ralf Hölzemer
6c22cab856 Move hardcoded theme colors from editor_node into editor_themes
(cherry picked from commit 991a433cb3)
2016-09-18 23:13:46 +02:00
Paulb23
71dc733ad2 Added ItemList get_v_scroll to docs
(cherry picked from commit 7d455fca71)
2016-09-18 23:13:40 +02:00
Paulb23
04ade4d639 Added get_v_scroll to item list, issue 5343
(cherry picked from commit 63fd8f863b)
2016-09-18 23:13:34 +02:00
Paulb23
20c3b35dd5 Added customisable grid color, issue 3781
(cherry picked from commit a82ecf6d80)
2016-09-18 23:13:13 +02:00
Andreas Haas
323dec7dd5 x11: fix x360 wireless gamepad mapping.
Uses hat values instead of buttons for the dpad now.
Fixes #6419

(cherry picked from commit 20bad652ef)
2016-09-18 23:13:06 +02:00
Gastronok
3b691907e9 Change the documentation to reflect that Directory.list_dir_begin()
returns true (not false) when a stream could not be initialized. (See, for
example,
https://github.com/godotengine/godot/blob/master/drivers/windows/dir_access_windows.cpp#L76
)

(cherry picked from commit cd82fafd58)
2016-09-18 23:12:55 +02:00
MarianoGNU
85eca7bc93 Explicitly initialize TextureProgress's initial angle value.
(Hopefully)
Fixes #3856
Fixes #6426
Fixes #6344

(cherry picked from commit ae4f7cbc2c)
2016-09-18 23:12:48 +02:00
bebae
2e6ce4b362 fixed wrong placement of AcceptDialog Buttons issue-6143
(cherry picked from commit dd9189aac4)
2016-09-18 23:12:39 +02:00
Paulb23
a1df4f138c Document itemlist disable tooltip
(cherry picked from commit 607d602493)
2016-09-18 23:12:30 +02:00
Paulb23
0aad82e921 Ability to disable item list tooltip, issue 6240
(cherry picked from commit 62a968b1c6)
2016-09-18 23:12:23 +02:00
Paulb23
aae720e488 Added setting to change current script background color, issue 5450
(cherry picked from commit 9e92fcaef9)
2016-09-18 23:12:15 +02:00
Geequlim
772a590261 Fix dialogs in ProjectManage don't with editor theme issue
(cherry picked from commit c1f23bb6af)
2016-09-18 23:11:50 +02:00
Pedro J. Estébanez
f90370886f Fix (potentially) Android libs packaging issue (#5645)
(cherry picked from commit e9065632c6)
2016-09-18 23:11:18 +02:00
Pedro J. Estébanez
c44757c2b7 Expose light shadow color to canvas item shaders
(cherry picked from commit 0960887625)
2016-09-18 23:11:08 +02:00
Pedro J. Estébanez
ffe5ecd67d Rename misleading define
The macro USE_LIGHT_SHADOW_COLOR actually was being defined when the shader used SHADOW (the output shadow color), not the shadow color set for the light so it's better named USE_OUTPUT_SHADOW_COLOR. In 3D there's not that difference but renaming as well for consistency.

(cherry picked from commit b69e422af9)
2016-09-18 23:10:26 +02:00
Juan Linietsky
e0ddef3164 Do not expose resource/ properties in sectioned property editor, closes #6396
(cherry picked from commit 0094c30938)
2016-09-18 23:10:14 +02:00
Juan Linietsky
7178399548 Added option for UVs (and tangents) in adding sphere for ImmediateGeometry, closes #6398
(cherry picked from commit f31400c04d)
2016-09-18 23:09:41 +02:00
supaiku
c007d31e52 Always show output panel when debugging
(cherry picked from commit 8514eaf34b)
2016-09-18 23:07:06 +02:00
supaiku
3f30a22cb0 Show object string cast instead of object id in debugger
(cherry picked from commit 0108e7c33a)
2016-09-18 23:06:51 +02:00
volzhs
d6dc8f4644 Select newly created folder on Directory dialog
(cherry picked from commit 28a0ed75ba)
2016-09-18 23:06:46 +02:00
Răzvan Cosmin Rădulescu
c4f79716d3 Clean up GDScript template
(cherry picked from commit 00e743b76a)
2016-09-18 23:05:45 +02:00
Kazuo256
4a9461fded Add http method and request data parameters
For HTTPRequest::request

(cherry picked from commit c53e5c555a)
2016-09-18 23:05:40 +02:00
Rémi Verschelde
49dd7b38bc Remove tools/script_plugins, demos of the old plugin API
They are superseded by the official demos in
https://github.com/godotengine/godot-demo-projects/tree/master/plugins

(cherry picked from commit 3b3502b758)
2016-09-18 23:05:16 +02:00
Rémi Verschelde
bfcfb58efc Merge tools/docdump in tools/doc
Reduces clutter in the tools folder.

(cherry picked from commit 6a4ba76836)
2016-09-18 23:05:07 +02:00
Rémi Verschelde
ed96689d8c Move various scripts to the "scripts" folder
Thus cleaning up the "tools" folder a bit.

(cherry picked from commit ae9729b6df)
2016-09-18 23:05:00 +02:00
Rémi Verschelde
125a9f0b06 Remove obsolete Win32 libraries that everyone had forgotten about
(cherry picked from commit 08e5e8794a)
2016-09-18 23:04:52 +02:00
Rémi Verschelde
fd58f8dce8 Move templates and distribution stuff to tools/dist
Also removed the obsolete iOS xcode template.

(cherry picked from commit 3efe1231f0)
2016-09-18 23:04:26 +02:00
Andreas Haas
adcf45b627 Update gamepad mappings from community db.
(cherry picked from commit 808bd53934)
2016-09-18 23:03:22 +02:00
Rémi Verschelde
48d1e8bd4e InputEvent: Fix event comparisons when type is NONE
Was a regression from 2e5a4cb5ca.
Fixes #6376.

(cherry picked from commit eff6519aaf)
2016-09-18 23:03:10 +02:00
Waldson Patrício
73b40d1457 Fixes LineEdit text selection with mouse selecting more than intended
(cherry picked from commit 3d84973184)
2016-09-18 23:02:57 +02:00
Joscha
e7772e43d3 Tilemap editor: Bucket tool - allow deleting and replacing of tiles
(cherry picked from commit acd41d964a)
2016-09-18 23:02:46 +02:00
Rémi Verschelde
de5f49aac5 i18n: Update list of supported locales based off glibc
Fixes #5733, fixes #6214.

(cherry picked from commit 54e97e5ee6)
2016-09-18 23:02:14 +02:00
Rémi Verschelde
2ab7e6daab i18n: Sync translations from Weblate
Translator credits added manually based on Weblate git log.
Adds Catalan, Danish and Norwegian Bokmål initial translations.

Those were initially translations for the master branch, merged
against the 2.1 template.
2016-09-01 19:33:28 +02:00
Rémi Verschelde
68c7da5a35 classref: Sync with current source 2016-09-01 18:56:48 +02:00
Mark Nokalt
a3a065b458 editor: Add mouse position information in TileMap
(cherry picked from commit cd71fcb097)
2016-09-01 08:46:23 +02:00
Mario Schlack
9ea76ff46d Hide the mouse cursor when MOUSE_MODE_CAPTURED is activated.
(cherry picked from commit f0b6a242cc)
2016-09-01 08:46:03 +02:00
Andreas Haas
cd6afd5f1d Fix crash when trying to access the guid of an unavailable Gamepad.
Throws an error now.

(cherry picked from commit 02a8604906)
2016-09-01 08:45:51 +02:00
volzhs
265715f5b2 Show last added action on Input Map and implement InputEvent "=="
(cherry picked from commit 2e5a4cb5ca)
2016-09-01 08:45:37 +02:00
volzhs
cd8beea3bf Prevent to add node to selection when node is not inside tree
(cherry picked from commit 4857eabddb)
2016-09-01 08:45:15 +02:00
George Marques
0657d43960 Better document the BaseButton signals
(cherry picked from commit 141360ed82)
2016-09-01 08:44:52 +02:00
George Marques
a21b9caa2a Add button_down and button_up signals
(cherry picked from commit 8a1b1ab6d6)
2016-09-01 08:44:45 +02:00
caryoscelus
83864514f9 fix string iterator
Since strings are null-terminated, size() returns incorrect length,
so use length() instead.

fixes #6287

(cherry picked from commit 810fbb70ae)
2016-09-01 08:44:30 +02:00
Ignacio Etcheverry
b1ea299edf Matrix32: Add constructor that takes six real_t params
(cherry picked from commit 3578800230)
2016-09-01 08:44:22 +02:00
Ignacio Etcheverry
103b04e529 DocData: Fix null reference not detected correctly
(cherry picked from commit b81725b203)
2016-09-01 08:44:08 +02:00
Mason Ashbridge
07caf4438d Slider value accounts for grabber offset
(cherry picked from commit fb54ba6397)
2016-09-01 08:43:59 +02:00
volzhs
6df46803a7 Make LineEdit not to cover whole line when rename node
(cherry picked from commit ff22db3b21)
2016-09-01 08:42:49 +02:00
Pedro J. Estébanez
cccc35e427 Improve/fix GridMap editor
Fix cursor/palette update on tile eyedropping
Fix editor not cleaning its state when becoming inactive, which leaves indicators behind among other issues
Fix/improve menu/keyboard shortcuts
Merge 'Gridmap Editor' and 'Grid Map' settings into the latter

(cherry picked from commit 7d35973486)
2016-09-01 08:41:31 +02:00
Gau o fthe Veldt
fa1f5e55de Documentation for most of ItemList control.
The icon stuff is incomplete since I haven't used icons.

(cherry picked from commit f9e931bf12)
2016-09-01 08:41:18 +02:00
Ignacio Etcheverry
6a563949c7 DocData: Fix duplicated parenthesis for default values
(cherry picked from commit 9e6b53c8dd)
2016-09-01 08:41:12 +02:00
Franklin Sobrinho
f9aeb91850 Implemented UndoRedo mergeable modes
(cherry picked from commit debf574df3)
2016-09-01 08:41:04 +02:00
Franklin Sobrinho
71a9efe604 Update Globals and EditorSettings docs
(cherry picked from commit 038e99e107)
2016-09-01 08:40:54 +02:00
Franklin Sobrinho
5f9e6d2b48 Added add_property_info function to Globals and EditorSettings classes
(cherry picked from commit 9f242ed6e5)
2016-09-01 08:40:49 +02:00
Franklin Sobrinho
6327fc47c8 Better editor settings for the FileSystem dock
* Save the current display mode when changing it from the dock

(cherry picked from commit f6b39827b1)
2016-09-01 08:40:23 +02:00
Franklin Sobrinho
3cbd6b8701 Fix editor glitches when the mesh/material preview is shown
(cherry picked from commit a4c3d2dc89)
2016-09-01 08:40:16 +02:00
Franklin Sobrinho
4890db7fef Small usability improvements on the TileMap editor tile palette.
* The column width changes with the zoom, now the icons don't overlap.
  * Added a tile hsepation setting.
  * Added a setting to show/hide tile names.

(cherry picked from commit 0fa26cd850)
2016-09-01 08:40:08 +02:00
Franklin Sobrinho
df3d2b25d8 Update EditorPlugin doc
(cherry picked from commit a27d2e4c29)
2016-09-01 08:39:58 +02:00
Franklin Sobrinho
743c63670e Expose additional functions for the EditorPlugin class
(cherry picked from commit 104653f9eb)
2016-09-01 08:39:52 +02:00
Daniel J. Ramirez
e26acc39da 2d collision shape icons now uses the color for shape icons
(cherry picked from commit cbad6b3fae)
2016-09-01 08:39:09 +02:00
Ignacio Etcheverry
1a53c4d3c2 Confirm code completion with numpad key ENTER
(cherry picked from commit e9f9e00bd9)
2016-09-01 08:38:34 +02:00
Andreas Haas
37fc61f986 x11: Use proper sonames for loading libXrandr.
(cherry picked from commit f59860f464)
2016-09-01 08:38:24 +02:00
Daniel J. Ramirez
16fc229e5d Zoom texture region via mouse wheel
(cherry picked from commit 1e7d0c6ac1)
2016-09-01 08:37:55 +02:00
Ignacio Etcheverry
4f07998552 Device Input dialog now uses containers
(cherry picked from commit 9483d3cbf9)
2016-09-01 08:34:05 +02:00
Rémi Verschelde
3b7ab73cab i18n: Merge PO files with current template 2016-08-10 21:31:06 +02:00
Rémi Verschelde
bbb543735c i18n: Sync template with current source 2016-08-10 21:30:57 +02:00
Rémi Verschelde
ed931d3b59 i18n: Sync translations from Weblate
Translator credits added manually based on Weblate git log.

(cherry picked from commit 221d81a26d)
2016-08-10 21:28:05 +02:00
Rémi Verschelde
720305d98e classref: Sync with current source 2016-08-10 21:28:01 +02:00
Rémi Verschelde
676b60a8b5 i18n: Add a README file to point to the Weblate repo
(cherry picked from commit 807c615148)
2016-08-10 21:27:45 +02:00
marcelofg55
0c76ba32cc Crashfix for OSX on Sierra beta
(cherry picked from commit bf320fd4ea)
2016-08-09 18:47:13 +02:00
Rémi Verschelde
c5e2c83dcd Release 2.1-stable
\o/
2016-08-09 09:52:15 +02:00
Rémi Verschelde
9cc700a0ab OSX Info.plist: no longer dev version
This should really be dehardcoded somehow.
2016-08-09 09:51:58 +02:00
Juan Linietsky
569966f3bb prevent bug due to scripts not working in editor and notifier sending signals to it.
(cherry picked from commit 37b5e99bc2)
2016-08-09 00:13:31 +02:00
Juan Linietsky
58556f5f95 Fixed bug in make_dir_recursive, closes #6016
(cherry picked from commit df6dbadc3e)
2016-08-08 23:45:39 +02:00
Rémi Verschelde
229b172977 Merge pull request #6078 from eska014/2.1-fix-call_func
Revert documentation of return type for FuncRef::call_func from b80c42e
2016-08-08 18:23:43 +02:00
Skyfrit
c56ea7cf91 Android: Rename values-zh to values-zh-rCN (#6063)
(cherry picked from commit 4f6a21b0df)
2016-08-08 18:15:55 +02:00
Skyfrit
1913e4a040 Android: Add support for Traditional Chinese (HK) (#6061)
(cherry picked from commit 664b5b5137)
2016-08-08 18:15:49 +02:00
Skyfrit
2b35ba4815 Android: Add support for Traditional Chinese (TW) (#6061)
(cherry picked from commit 8ab4acd17f)
2016-08-08 18:15:43 +02:00
Ignacio Etcheverry
d853eb2fb7 Project Manager: Fix and improve unhandled input
(cherry picked from commit f3a75a42dd)
2016-08-08 18:15:03 +02:00
Andreas Haas
36eeedb357 Remove unused function in Project Manager.
This has been deprecated by #5993

(cherry picked from commit 0df40cc29b)
2016-08-08 18:14:57 +02:00
Andreas Haas
5f18c5cb46 Fix steam controller gamepad mapping
The left stick click was missing

(cherry picked from commit e52567bd29)
2016-08-08 18:14:51 +02:00
Bojidar Marinov
f25e9a08e1 Fix #5891 by not expecting the script instance to be a GDInstance
It could be a placeholder instance as well

(cherry picked from commit 76ea995228)
2016-08-08 18:14:44 +02:00
MSC
4f8f9a4dbf Some additions to the OS documentation (#6037)
(cherry picked from commit 7b05b4c83c)
2016-08-08 18:14:35 +02:00
Saracen
dd97502788 TextureRegionEditor snap_mode fix.
(cherry picked from commit b578cf4da8)
2016-08-08 18:14:29 +02:00
Hubert Jarosz
d55304c56f [ci skip] update Raycast documentation
clarification that set_cast_to needs LOCAL point
and get_collision_point gives GLOBAL point

(cherry picked from commit 1445553fea)
2016-08-08 18:14:14 +02:00
eska
03a4b8cbc8 Revert documentation of return type for FuncRef::call_func from b80c42e
bind_native_method doesn't support this style of return type documentation.
2016-08-08 17:49:30 +02:00
Rémi Verschelde
2f0df52fe7 Bump version to 2.1-rc2 2016-08-03 17:53:53 +02:00
marcelofg55
fd6f62fd9a Fix set_window_size not setting the correct size on OSX
(cherry picked from commit 38de4d24ef)
2016-08-03 17:52:10 +02:00
5623 changed files with 385308 additions and 376729 deletions

98
.clang-format Normal file
View File

@@ -0,0 +1,98 @@
---
BasedOnStyle: LLVM
# 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 (initial sync: Clang 3.9.1).
...
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
# AlignConsecutiveAssignments: false
# AlignConsecutiveDeclarations: false
# AlignEscapedNewlinesLeft: false
# 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
# BeforeCatch: false
# BeforeElse: false
# IndentBraces: false
# BreakBeforeBinaryOperators: None
# BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: false
# BreakConstructorInitializersBeforeComma: false
# BreakAfterJavaFieldAnnotations: false
# BreakStringLiterals: true
ColumnLimit: 0
# CommentPragmas: '^ IWYU pragma:'
# ConstructorInitializerAllOnOneLineOrOnePerLine: false
# ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
# DerivePointerAlignment: false
# DisableFormat: false
# ExperimentalAutoDetectBinPacking: false
# ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '".*"'
Priority: 1
- Regex: '^<.*\.h>'
Priority: 2
- Regex: '^<.*'
Priority: 3
# IncludeIsMainRegex: '$'
IndentCaseLabels: true
IndentWidth: 4
# IndentWrappedFunctionNames: false
# JavaScriptQuotes: Leave
# JavaScriptWrapImports: true
# KeepEmptyLinesAtTheStartOfBlocks: true
# MacroBlockBegin: ''
# MacroBlockEnd: ''
# MaxEmptyLinesToKeep: 1
# NamespaceIndentation: None
ObjCBlockIndentWidth: 4
# ObjCSpaceAfterProperty: false
# ObjCSpaceBeforeProtocolList: true
# PenaltyBreakBeforeFirstCallParameter: 19
# PenaltyBreakComment: 300
# PenaltyBreakFirstLessLess: 120
# PenaltyBreakString: 1000
# PenaltyExcessCharacter: 1000000
# PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
# ReflowComments: true
SortIncludes: true
# SpaceAfterCStyleCast: false
# SpaceBeforeAssignmentOperators: true
# SpaceBeforeParens: ControlStatements
# SpaceInEmptyParentheses: false
# SpacesBeforeTrailingComments: 1
# SpacesInAngles: false
# SpacesInContainerLiterals: true
# SpacesInCStyleCastParentheses: false
# SpacesInParentheses: false
# SpacesInSquareBrackets: false
Standard: Cpp03
TabWidth: 4
UseTab: Always
...

1
.gitattributes vendored
View File

@@ -5,5 +5,6 @@ drivers/* linguist-vendored
*.cpp eol=lf
*.h eol=lf
*.mm eol=lf
*.py eol=lf
*.hpp eol=lf

37
.gitignore vendored
View File

@@ -1,29 +1,30 @@
# Godot auto generated files
platform/server/logo.h
core/global_defaults.cpp
core/method_bind_ext.inc
core/method_bind.inc
core/script_encryption_key.cpp
core/version_generated.h
drivers/gles2/shaders/*.h
drivers/unix/os_unix_global_settings_path.cpp
editor/builtin_fonts.h
editor/certs_compressed.h
editor/doc_data_compressed.h
editor/editor_icons.cpp
editor/register_exporters.cpp
editor/translations.h
log.txt
main/app_icon.h
main/splash.h
make.bat
modules/register_module_types.cpp
platform/android/logo.h
platform/bb10/logo.h
platform/iphone/logo.h
platform/javascript/logo.h
platform/osx/logo.h
platform/server/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
drivers/unix/os_unix_global_settings_path.cpp
tools/editor/register_exporters.cpp
tools/editor/doc_data_compressed.h
tools/editor/certs_compressed.h
tools/editor/editor_icons.cpp
tools/editor/translations.h
tools/editor/builtin_fonts.h
.fscache
make.bat
log.txt
# Documentation generated by doxygen or from classes.xml
doc/_build/

View File

@@ -14,10 +14,12 @@ env:
- GODOT_TARGET=iphone
- GODOT_TARGET=osx
- GODOT_TARGET=x11
- GODOT_TARGET=android
#- GODOT_TARGET=android
- GODOT_TARGET=windows
matrix:
include:
- env: STATIC_CHECKS=yes
exclude:
- os: linux
env: GODOT_TARGET=iphone
@@ -42,6 +44,9 @@ matrix:
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-3.9
packages:
- build-essential
- scons
@@ -65,6 +70,9 @@ addons:
- g++-mingw-w64-x86-64
- mingw-w64
# For style checks.
- clang-format-3.9
before_script:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; brew install scons; fi
@@ -75,4 +83,8 @@ before_script:
fi
script:
- scons platform=$GODOT_TARGET CXX=$CXX openssl=builtin
- if [ "$STATIC_CHECKS" = "yes" ]; then
sh ./misc/travis/clang-format.sh;
else
scons platform=$GODOT_TARGET CXX=$CXX openssl=builtin;
fi

76
AUTHORS.md Normal file
View File

@@ -0,0 +1,76 @@
# 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.
## Original authors
Juan Linietsky (reduz)
Ariel Manzur (punto-)
## Developers
(in alphabetical order, with 10 commits or more excluding merges)
Alexander Holland (AlexHolly)
Alexey Velikiy (jonyrock)
Andreas Haas (Hinsbart)
Anton Yabchinskiy (a12n)
Aren Villanueva (kurikaesu)
Ariel Manzur (punto-)
Bastiaan Olij (BastiaanOlij)
Bojidar Marinov (bojidar-bg)
Błażej Szczygieł (zaps166)
Carl Olsson (not-surt)
Dana Olson (adolson)
Daniel J. Ramirez (djrm)
Fabio Alessandrelli (Faless)
Ferenc Arn (tagcup)
Franklin Sobrinho (TheHX)
Geequlim
Gen (dbsGen)
George Marques (vnen)
Guilherme Felipe (guilhermefelipecgs)
Hein-Pieter van Braam (hpvb)
Hubert Jarosz (Marqin)
Ignacio Etcheverry (neikeq)
J08nY
Johan Manuel (29jm)
Joshua Grams (JoshuaGrams)
Juan Linietsky (reduz)
Julian Murgia (StraToN)
Kostadin Damyanov (Max-Might)
L. Krause (eska014)
Marcelo Fernandez (marcelofg55)
Mariano Javier Suligoy (MarianoGnu)
Mario Schlack (hurikhan)
Masoud BH (masoudbh3)
Nathan Warden (NathanWarden)
Ovnuniarchos
Patrick (firefly2442)
Paul Batty (Paulb23)
Pawel Kowal (pkowal1982)
Pedro J. Estébanez (RandomShaper)
Ralf Hölzemer (rollenrolm)
RayKoopa
Rémi Verschelde (akien-mga)
SaracenOne
Thomas Herzog (karroffel)
V. Vamsi Krishna (vkbsb)
Vinzenz Feenstra (vinzenz)
Zher Huei Lee (leezh)
ZuBsPaCe
박한얼 (volzhs)
est31
marynate
mrezai
romulox-x
sanikoyes
yg2f (SuperUserNameMan)

View File

@@ -3,7 +3,8 @@
************************************************************************
Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.
Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.
Copyright (c) 2014-2017 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

View File

@@ -1,30 +1,66 @@
![GODOT](/logo.png)
[![GODOT](/logo.png)](https://godotengine.org)
https://godotengine.org
## Godot Engine
### The Engine
Homepage: https://godotengine.org
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.
#### 2D and 3D cross-platform game engine
### About
Godot Engine 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, Mac OSX, Windows) as well as mobile
(Android, iOS) and web-based (HTML5) platforms.
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. Godot is a member project of the [Software Freedom Conservancy](https://sfconservancy.org)
#### Free, open source and community-driven
### Documentation
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
not-for-profit.
Documentation is hosted on [ReadTheDocs](http://docs.godotengine.org).
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.
### Binary Downloads, Community, etc.
### Getting the engine
Binary downloads, community, etc. can be found in Godot homepage:
#### Binary downloads
https://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 docs for compilation instructions for every platform:
http://docs.godotengine.org/en/latest/reference/_compiling.html
[See the official docs](http://docs.godotengine.org/en/latest/reference/_compiling.html)
for compilation instructions for every supported platform.
### Community
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 developers, the best way is to join the
[#godotengine IRC channel](https://webchat.freenode.net/?channels=godotengine)
on Freenode.
### Documentation and demos
The official documentation is hosted on [ReadTheDocs](http://docs.godotengine.org).
It is maintained by the Godot community in its own [GitHub repository](https://github.com/godotengine/godot-docs).
The [class reference](http://docs.godotengine.org/en/latest/classes/_classes.html)
is also accessible from within the engine.
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 provided by the community,
such as text and video tutorials, demos, etc. Consult the [community channels](https://godotengine.org/community)
for more info.
[![Build Status](https://travis-ci.org/godotengine/godot.svg?branch=master)](https://travis-ci.org/godotengine/godot)
[![Code Triagers Badge](http://www.codetriage.com/godotengine/godot/badges/users.svg)](http://www.codetriage.com/godotengine/godot)

View File

@@ -1,4 +1,7 @@
EnsureSConsVersion(0,14);
#!/usr/bin/env python
EnsureSConsVersion(0, 14)
import string
@@ -12,163 +15,183 @@ methods.update_version()
# scan possible build platforms
platform_list = [] # list of platforms
platform_opts = {} # options for each platform
platform_flags = {} # flags for each platform
platform_list = [] # list of platforms
platform_opts = {} # options for each platform
platform_flags = {} # flags for each platform
active_platforms=[]
active_platform_ids=[]
platform_exporters=[]
global_defaults=[]
active_platforms = []
active_platform_ids = []
platform_exporters = []
global_defaults = []
for x in glob.glob("platform/*"):
if (not os.path.isdir(x) or not os.path.exists(x+"/detect.py")):
continue
tmppath="./"+x
if (not os.path.isdir(x) or not os.path.exists(x + "/detect.py")):
continue
tmppath = "./" + x
sys.path.append(tmppath)
import detect
sys.path.append(tmppath)
import detect
if (os.path.exists(x+"/export/export.cpp")):
platform_exporters.append(x[9:])
if (os.path.exists(x+"/globals/global_defaults.cpp")):
global_defaults.append(x[9:])
if (detect.is_active()):
active_platforms.append( detect.get_name() )
active_platform_ids.append(x);
if (detect.can_build()):
x=x.replace("platform/","") # rest of world
x=x.replace("platform\\","") # win32
platform_list+=[x]
platform_opts[x]=detect.get_opts()
platform_flags[x]=detect.get_flags()
sys.path.remove(tmppath)
sys.modules.pop('detect')
if (os.path.exists(x + "/export/export.cpp")):
platform_exporters.append(x[9:])
if (os.path.exists(x + "/globals/global_defaults.cpp")):
global_defaults.append(x[9:])
if (detect.is_active()):
active_platforms.append(detect.get_name())
active_platform_ids.append(x)
if (detect.can_build()):
x = x.replace("platform/", "") # rest of world
x = x.replace("platform\\", "") # win32
platform_list += [x]
platform_opts[x] = detect.get_opts()
platform_flags[x] = detect.get_flags()
sys.path.remove(tmppath)
sys.modules.pop('detect')
module_list=methods.detect_modules()
module_list = methods.detect_modules()
#print "Detected Platforms: "+str(platform_list)
# print "Detected Platforms: "+str(platform_list)
methods.save_active_platforms(active_platforms,active_platform_ids)
methods.save_active_platforms(active_platforms, active_platform_ids)
custom_tools=['default']
custom_tools = ['default']
platform_arg = ARGUMENTS.get("platform", False)
platform_arg = ARGUMENTS.get("platform", ARGUMENTS.get("p", False))
if (os.name=="posix"):
pass
elif (os.name=="nt"):
if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"):
custom_tools=['mingw']
if (os.name == "posix"):
pass
elif (os.name == "nt"):
if (os.getenv("VSINSTALLDIR") == None or platform_arg == "android"):
custom_tools = ['mingw']
env_base=Environment(tools=custom_tools);
env_base = Environment(tools=custom_tools)
if 'TERM' in os.environ:
env_base['ENV']['TERM'] = os.environ['TERM']
env_base.AppendENVPath('PATH', os.getenv('PATH'))
env_base.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
env_base.global_defaults=global_defaults
env_base.android_maven_repos=[]
env_base.android_dependencies=[]
env_base.android_java_dirs=[]
env_base.android_res_dirs=[]
env_base.android_aidl_dirs=[]
env_base.android_jni_dirs=[]
env_base.android_default_config=[]
env_base.android_manifest_chunk=""
env_base.android_permission_chunk=""
env_base.android_appattributes_chunk=""
env_base.disabled_modules=[]
env_base.use_ptrcall=False
env_base.split_drivers=False
env_base.global_defaults = global_defaults
env_base.android_maven_repos = []
env_base.android_dependencies = []
env_base.android_gradle_plugins = []
env_base.android_gradle_classpath = []
env_base.android_java_dirs = []
env_base.android_res_dirs = []
env_base.android_aidl_dirs = []
env_base.android_jni_dirs = []
env_base.android_default_config = []
env_base.android_manifest_chunk = ""
env_base.android_permission_chunk = ""
env_base.android_appattributes_chunk = ""
env_base.disabled_modules = []
env_base.use_ptrcall = False
env_base.split_drivers = False
env_base.__class__.android_add_maven_repository=methods.android_add_maven_repository
env_base.__class__.android_add_dependency=methods.android_add_dependency
env_base.__class__.android_add_java_dir=methods.android_add_java_dir
env_base.__class__.android_add_res_dir=methods.android_add_res_dir
env_base.__class__.android_add_aidl_dir=methods.android_add_aidl_dir
env_base.__class__.android_add_jni_dir=methods.android_add_jni_dir
env_base.__class__.android_add_default_config=methods.android_add_default_config
env_base.__class__.android_add_maven_repository = methods.android_add_maven_repository
env_base.__class__.android_add_dependency = methods.android_add_dependency
env_base.__class__.android_add_java_dir = methods.android_add_java_dir
env_base.__class__.android_add_res_dir = methods.android_add_res_dir
env_base.__class__.android_add_aidl_dir = methods.android_add_aidl_dir
env_base.__class__.android_add_jni_dir = methods.android_add_jni_dir
env_base.__class__.android_add_default_config = methods.android_add_default_config
env_base.__class__.android_add_to_manifest = methods.android_add_to_manifest
env_base.__class__.android_add_to_permissions = methods.android_add_to_permissions
env_base.__class__.android_add_to_attributes = methods.android_add_to_attributes
env_base.__class__.android_add_gradle_plugin = methods.android_add_gradle_plugin
env_base.__class__.android_add_gradle_classpath = methods.android_add_gradle_classpath
env_base.__class__.disable_module = methods.disable_module
env_base.__class__.add_source_files = methods.add_source_files
env_base.__class__.use_windows_spawn_fix = methods.use_windows_spawn_fix
env_base.__class__.split_lib = methods.split_lib
env_base["x86_opt_gcc"]=False
env_base["x86_opt_vc"]=False
env_base["armv7_opt_gcc"]=False
env_base["x86_libtheora_opt_gcc"] = False
env_base["x86_libtheora_opt_vc"] = False
# Build options
customs = ['custom.py']
profile = ARGUMENTS.get("profile", False)
if profile:
import os.path
if os.path.isfile(profile):
customs.append(profile)
elif os.path.isfile(profile+".py"):
customs.append(profile+".py")
import os.path
if os.path.isfile(profile):
customs.append(profile)
elif os.path.isfile(profile + ".py"):
customs.append(profile + ".py")
opts = Variables(customs, ARGUMENTS)
# Target build options
opts.Add('arch', "Platform-dependent architecture (arm/arm64/x86/x64/mips/etc)", '')
opts.Add('bits', "Target platform bits (default/32/64/fat)", 'default')
opts.Add('p', "Platform (alias for 'platform')", '')
opts.Add('platform', "Target platform: any in " + str(platform_list), '')
opts.Add('target', "Compilation target (debug/release_debug/release)", 'debug')
opts.Add('tools', "Build the tools a.k.a. the Godot editor (yes/no)", 'yes')
# Components
opts.Add('deprecated', "Enable deprecated features (yes/no)", 'yes')
opts.Add('gdscript', "Build GDSCript support (yes/no)", 'yes')
opts.Add('minizip', "Build minizip archive support (yes/no)", 'yes')
opts.Add('xml', "XML format support for resources (yes/no)", 'yes')
# Advanced options
opts.Add('disable_3d', "Disable 3D nodes for smaller executable (yes/no)", 'no')
opts.Add('disable_advanced_gui', "Disable advance 3D gui nodes and behaviors (yes/no)", 'no')
opts.Add('extra_suffix', "Custom extra suffix added to the base filename of all generated binary files", '')
opts.Add('unix_global_settings_path', "UNIX-specific path to system-wide settings. Currently only used for templates", '')
opts.Add('verbose', "Enable verbose output for the compilation (yes/no)", 'yes')
opts.Add('vsproj', "Generate Visual Studio Project. (yes/no)", 'no')
opts.Add('warnings', "Enable showing warnings during the compilation (yes/no)", 'yes')
# Thirdparty libraries
opts.Add('builtin_freetype', "Use the builtin freetype library (yes/no)", 'yes')
opts.Add('builtin_glew', "Use the builtin glew library (yes/no)", 'yes')
opts.Add('builtin_libmpcdec', "Use the builtin libmpcdec library (yes/no)", 'yes')
opts.Add('builtin_libogg', "Use the builtin libogg library (yes/no)", 'yes')
opts.Add('builtin_libpng', "Use the builtin libpng library (yes/no)", 'yes')
opts.Add('builtin_libtheora', "Use the builtin libtheora library (yes/no)", 'yes')
opts.Add('builtin_libvorbis', "Use the builtin libvorbis library (yes/no)", 'yes')
opts.Add('builtin_libwebp', "Use the builtin libwebp library (yes/no)", 'yes')
opts.Add('builtin_openssl', "Use the builtin openssl library (yes/no)", 'yes')
opts.Add('builtin_opus', "Use the builtin opus library (yes/no)", 'yes')
# (akien) Unbundling would require work in audio_stream_speex.{cpp,h}, but since speex was
# removed in 3.0+ and this is only to preserve compatibility in 2.1, I haven't worked on it.
# Patches welcome if anyone cares :)
opts.Add('builtin_speex', "Use the builtin speex library (yes/no)", 'yes')
opts.Add('builtin_squish', "Use the builtin squish library (yes/no)", 'yes')
opts.Add('builtin_zlib', "Use the builtin zlib library (yes/no)", 'yes')
# Environment setup
opts.Add("CXX", "C++ compiler")
opts.Add("CC", "C compiler")
opts.Add("CCFLAGS", "Custom flags for the C and C++ compilers")
opts.Add("CFLAGS", "Custom flags for the C compiler")
opts.Add("LINKFLAGS", "Custom flags for the linker")
opts=Variables(customs, ARGUMENTS)
opts.Add('target', 'Compile Target (debug/release_debug/release).', "debug")
opts.Add('arch', 'Platform dependent architecture (arm/arm64/x86/x64/mips/etc)', "")
opts.Add('bits', 'Compile Target Bits (default/32/64/fat).', "default")
opts.Add('platform','Platform: '+str(platform_list)+'.',"")
opts.Add('p','Platform (same as platform=).',"")
opts.Add('tools','Build Tools (Including Editor): (yes/no)','yes')
opts.Add('gdscript','Build GDSCript support: (yes/no)','yes')
opts.Add('vorbis','Build Ogg Vorbis Support: (yes/no)','yes')
opts.Add('opus','Build Opus Audio Format Support: (yes/no)','yes')
opts.Add('minizip','Build Minizip Archive Support: (yes/no)','yes')
opts.Add('squish','Squish BC Texture Compression in editor (yes/no)','yes')
opts.Add('theora','Theora Video (yes/no)','yes')
opts.Add('theoralib','Theora Video (yes/no)','no')
opts.Add('freetype','Freetype support in editor','builtin')
opts.Add('speex','Speex Audio (yes/no)','yes')
opts.Add('xml','XML Save/Load support (yes/no)','yes')
opts.Add('png','PNG Image loader support (yes/no)','yes')
opts.Add('jpg','JPG Image loader support (yes/no)','yes')
opts.Add('webp','WEBP Image loader support (yes/no)','yes')
opts.Add('dds','DDS Texture loader support (yes/no)','yes')
opts.Add('pvr','PVR (PowerVR) Texture loader support (yes/no)','yes')
opts.Add('etc1','etc1 Texture compression support (yes/no)','yes')
opts.Add('builtin_zlib','Use built-in zlib (yes/no)','yes')
opts.Add('openssl','Use OpenSSL (yes/no/builtin)','no')
opts.Add('musepack','Musepack Audio (yes/no)','yes')
opts.Add("CXX", "Compiler");
opts.Add("CCFLAGS", "Custom flags for the C++ compiler");
opts.Add("CFLAGS", "Custom flags for the C compiler");
opts.Add("LINKFLAGS", "Custom flags for the linker");
opts.Add('unix_global_settings_path', 'unix-specific path to system-wide settings. Currently only used by templates.','')
opts.Add('disable_3d', 'Disable 3D nodes for smaller executable (yes/no)', "no")
opts.Add('disable_advanced_gui', 'Disable advance 3D gui nodes and behaviors (yes/no)', "no")
opts.Add('colored', 'Enable colored output for the compilation (yes/no)', 'no')
opts.Add('deprecated','Enable deprecated features (yes/no)','yes')
opts.Add('extra_suffix', 'Custom extra suffix added to the base filename of all generated binary files.', '')
opts.Add('vsproj', 'Generate Visual Studio Project. (yes/no)', 'no')
# add platform specific options
for k in platform_opts.keys():
opt_list = platform_opts[k]
for o in opt_list:
opts.Add(o[0],o[1],o[2])
opt_list = platform_opts[k]
for o in opt_list:
opts.Add(o[0], o[1], o[2])
for x in module_list:
opts.Add('module_'+x+'_enabled', "Enable module '"+x+"'.", "yes")
opts.Add('module_' + x + '_enabled', "Enable module '" + x + "' (yes/no)", "yes")
opts.Update(env_base) # update environment
Help(opts.GenerateHelpText(env_base)) # generate help
opts.Update(env_base) # update environment
Help(opts.GenerateHelpText(env_base)) # generate help
# add default include paths
env_base.Append(CPPPATH=['#core','#core/math','#tools','#drivers','#'])
env_base.Append(CPPPATH=['#core', '#core/math', '#editor', '#drivers', '#'])
# configure ENV for platform
env_base.platform_exporters=platform_exporters
env_base.platform_exporters = platform_exporters
"""
sys.path.append("./platform/"+env_base["platform"])
@@ -178,276 +201,233 @@ sys.path.remove("./platform/"+env_base["platform"])
sys.modules.pop('detect')
"""
if (env_base['target']=='debug'):
env_base.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC']);
env_base.Append(CPPFLAGS=['-DSCI_NAMESPACE'])
if (env_base['target'] == 'debug'):
env_base.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC'])
env_base.Append(CPPFLAGS=['-DSCI_NAMESPACE'])
if (env_base['deprecated']!='no'):
env_base.Append(CPPFLAGS=['-DENABLE_DEPRECATED']);
if (env_base['deprecated'] != 'no'):
env_base.Append(CPPFLAGS=['-DENABLE_DEPRECATED'])
env_base.platforms = {}
selected_platform =""
selected_platform = ""
if env_base['platform'] != "":
selected_platform=env_base['platform']
selected_platform = env_base['platform']
elif env_base['p'] != "":
selected_platform=env_base['p']
env_base["platform"]=selected_platform
selected_platform = env_base['p']
env_base["platform"] = selected_platform
if selected_platform in platform_list:
sys.path.append("./platform/"+selected_platform)
import detect
if "create" in dir(detect):
env = detect.create(env_base)
else:
env = env_base.Clone()
sys.path.append("./platform/" + selected_platform)
import detect
if "create" in dir(detect):
env = detect.create(env_base)
else:
env = env_base.Clone()
if env['vsproj']=="yes":
env.vs_incs = []
env.vs_srcs = []
if env['vsproj'] == "yes":
env.vs_incs = []
env.vs_srcs = []
def AddToVSProject( sources ):
for x in sources:
if type(x) == type(""):
fname = env.File(x).path
else:
fname = env.File(x)[0].path
pieces = fname.split(".")
if len(pieces)>0:
basename = pieces[0]
basename = basename.replace('\\\\','/')
env.vs_srcs = env.vs_srcs + [basename + ".cpp"]
env.vs_incs = env.vs_incs + [basename + ".h"]
#print basename
env.AddToVSProject = AddToVSProject
def AddToVSProject(sources):
for x in sources:
if type(x) == type(""):
fname = env.File(x).path
else:
fname = env.File(x)[0].path
pieces = fname.split(".")
if len(pieces) > 0:
basename = pieces[0]
basename = basename.replace('\\\\', '/')
env.vs_srcs = env.vs_srcs + [basename + ".cpp"]
env.vs_incs = env.vs_incs + [basename + ".h"]
# print basename
env.AddToVSProject = AddToVSProject
env.extra_suffix=""
env.extra_suffix = ""
if env["extra_suffix"] != '' :
env.extra_suffix += '.'+env["extra_suffix"]
if env["extra_suffix"] != '':
env.extra_suffix += '.' + env["extra_suffix"]
CCFLAGS = env.get('CCFLAGS', '')
env['CCFLAGS'] = ''
CCFLAGS = env.get('CCFLAGS', '')
env['CCFLAGS'] = ''
env.Append(CCFLAGS=string.split(str(CCFLAGS)))
env.Append(CCFLAGS=string.split(str(CCFLAGS)))
CFLAGS = env.get('CFLAGS', '')
env['CFLAGS'] = ''
CFLAGS = env.get('CFLAGS', '')
env['CFLAGS'] = ''
env.Append(CFLAGS=string.split(str(CFLAGS)))
env.Append(CFLAGS=string.split(str(CFLAGS)))
LINKFLAGS = env.get('LINKFLAGS', '')
env['LINKFLAGS'] = ''
LINKFLAGS = env.get('LINKFLAGS', '')
env['LINKFLAGS'] = ''
env.Append(LINKFLAGS=string.split(str(LINKFLAGS)))
env.Append(LINKFLAGS=string.split(str(LINKFLAGS)))
flag_list = platform_flags[selected_platform]
for f in flag_list:
if not (f[0] in ARGUMENTS): # allow command line to override platform flags
env[f[0]] = f[1]
flag_list = platform_flags[selected_platform]
for f in flag_list:
if not (f[0] in ARGUMENTS): # allow command line to override platform flags
env[f[0]] = f[1]
#must happen after the flags, so when flags are used by configure, stuff happens (ie, ssl on x11)
detect.configure(env)
# must happen after the flags, so when flags are used by configure, stuff happens (ie, ssl on x11)
detect.configure(env)
# TODO: Add support to specify different levels of warning, e.g. only critical/significant, instead of on/off
if (env["warnings"] == "yes"):
if (os.name == "nt" and os.getenv("VSINSTALLDIR")): # MSVC, needs to stand out of course
env.Append(CCFLAGS=['/W4'])
else: # Rest of the world
env.Append(CCFLAGS=['-Wall'])
else:
if (os.name == "nt" and os.getenv("VSINSTALLDIR")): # MSVC
env.Append(CCFLAGS=['/w'])
else: # Rest of the world
env.Append(CCFLAGS=['-w'])
if (env["freetype"]!="no"):
env.Append(CCFLAGS=['-DFREETYPE_ENABLED'])
if (env["freetype"]=="builtin"):
env.Append(CPPPATH=['#drivers/freetype'])
env.Append(CPPPATH=['#drivers/freetype/freetype/include'])
#env['platform_libsuffix'] = env['LIBSUFFIX']
suffix = "." + selected_platform
#env['platform_libsuffix'] = env['LIBSUFFIX']
if (env["target"] == "release"):
if (env["tools"] == "yes"):
print("Tools can only be built with targets 'debug' and 'release_debug'.")
sys.exit(255)
suffix += ".opt"
env.Append(CCFLAGS=['-DNDEBUG'])
suffix="."+selected_platform
elif (env["target"] == "release_debug"):
if (env["tools"] == "yes"):
suffix += ".opt.tools"
else:
suffix += ".opt.debug"
else:
if (env["tools"] == "yes"):
suffix += ".tools"
else:
suffix += ".debug"
if (env["target"]=="release"):
if (env["tools"]=="yes"):
print("Tools can only be built with targets 'debug' and 'release_debug'.")
sys.exit(255)
suffix+=".opt"
if env["arch"] != "":
suffix += "." + env["arch"]
elif (env["bits"] == "32"):
suffix += ".32"
elif (env["bits"] == "64"):
suffix += ".64"
elif (env["bits"] == "fat"):
suffix += ".fat"
elif (env["target"]=="release_debug"):
if (env["tools"]=="yes"):
suffix+=".opt.tools"
else:
suffix+=".opt.debug"
else:
if (env["tools"]=="yes"):
suffix+=".tools"
else:
suffix+=".debug"
suffix += env.extra_suffix
if env["arch"] != "":
suffix += "."+env["arch"]
elif (env["bits"]=="32"):
suffix+=".32"
elif (env["bits"]=="64"):
suffix+=".64"
elif (env["bits"]=="fat"):
suffix+=".fat"
env["PROGSUFFIX"] = suffix + env["PROGSUFFIX"]
env["OBJSUFFIX"] = suffix + env["OBJSUFFIX"]
env["LIBSUFFIX"] = suffix + env["LIBSUFFIX"]
env["SHLIBSUFFIX"] = suffix + env["SHLIBSUFFIX"]
suffix+=env.extra_suffix
sys.path.remove("./platform/" + selected_platform)
sys.modules.pop('detect')
env["PROGSUFFIX"]=suffix+env["PROGSUFFIX"]
env["OBJSUFFIX"]=suffix+env["OBJSUFFIX"]
env["LIBSUFFIX"]=suffix+env["LIBSUFFIX"]
env["SHLIBSUFFIX"]=suffix+env["SHLIBSUFFIX"]
env.module_list = []
sys.path.remove("./platform/"+selected_platform)
sys.modules.pop('detect')
for x in module_list:
if env['module_' + x + '_enabled'] != "yes":
continue
tmppath = "./modules/" + x
sys.path.append(tmppath)
env.current_module = x
import config
if (config.can_build(selected_platform)):
config.configure(env)
env.module_list.append(x)
sys.path.remove(tmppath)
sys.modules.pop('config')
if (env.use_ptrcall):
env.Append(CPPFLAGS=['-DPTRCALL_ENABLED'])
env.module_list=[]
# to test 64 bits compiltion
# env.Append(CPPFLAGS=['-m64'])
for x in module_list:
if env['module_'+x+'_enabled'] != "yes":
continue
tmppath="./modules/"+x
sys.path.append(tmppath)
env.current_module=x
import config
if (config.can_build(selected_platform)):
config.configure(env)
env.module_list.append(x)
sys.path.remove(tmppath)
sys.modules.pop('config')
if (env['tools'] == 'yes'):
env.Append(CPPFLAGS=['-DTOOLS_ENABLED'])
if (env['disable_3d'] == 'yes'):
env.Append(CPPFLAGS=['-D_3D_DISABLED'])
if (env['gdscript'] == 'yes'):
env.Append(CPPFLAGS=['-DGDSCRIPT_ENABLED'])
if (env['disable_advanced_gui'] == 'yes'):
env.Append(CPPFLAGS=['-DADVANCED_GUI_DISABLED'])
if (env['minizip'] == 'yes'):
env.Append(CPPFLAGS=['-DMINIZIP_ENABLED'])
if (env.use_ptrcall):
env.Append(CPPFLAGS=['-DPTRCALL_ENABLED']);
if (env['xml'] == 'yes'):
env.Append(CPPFLAGS=['-DXML_ENABLED'])
if (env['musepack']=='yes'):
env.Append(CPPFLAGS=['-DMUSEPACK_ENABLED']);
if (env['verbose'] == 'no'):
methods.no_verbose(sys, env)
#if (env['openssl']!='no'):
# env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
# if (env['openssl']=="builtin"):
# env.Append(CPPPATH=['#drivers/builtin_openssl2'])
Export('env')
if (env["builtin_zlib"]=='yes'):
env.Append(CPPPATH=['#drivers/builtin_zlib/zlib'])
# build subdirs, the build order is dependent on link order.
# to test 64 bits compiltion
# env.Append(CPPFLAGS=['-m64'])
SConscript("core/SCsub")
SConscript("servers/SCsub")
SConscript("scene/SCsub")
SConscript("editor/SCsub")
SConscript("drivers/SCsub")
if (env_base['squish']=='yes'):
env.Append(CPPFLAGS=['-DSQUISH_ENABLED']);
SConscript("modules/SCsub")
SConscript("main/SCsub")
if (env['vorbis']=='yes'):
env.Append(CPPFLAGS=['-DVORBIS_ENABLED']);
if (env['opus']=='yes'):
env.Append(CPPFLAGS=['-DOPUS_ENABLED']);
SConscript("platform/" + selected_platform + "/SCsub") # build selected platform
# Microsoft Visual Studio Project Generation
if (env['vsproj']) == "yes":
if (env['theora']=='yes'):
env['theoralib']='yes'
env.Append(CPPFLAGS=['-DTHEORA_ENABLED']);
if (env['theoralib']=='yes'):
env.Append(CPPFLAGS=['-DTHEORALIB_ENABLED']);
AddToVSProject(env.core_sources)
AddToVSProject(env.main_sources)
AddToVSProject(env.modules_sources)
AddToVSProject(env.scene_sources)
AddToVSProject(env.servers_sources)
AddToVSProject(env.editor_sources)
if (env['png']=='yes'):
env.Append(CPPFLAGS=['-DPNG_ENABLED']);
if (env['dds']=='yes'):
env.Append(CPPFLAGS=['-DDDS_ENABLED']);
if (env['pvr']=='yes'):
env.Append(CPPFLAGS=['-DPVR_ENABLED']);
if (env['jpg']=='yes'):
env.Append(CPPFLAGS=['-DJPG_ENABLED']);
if (env['webp']=='yes'):
env.Append(CPPFLAGS=['-DWEBP_ENABLED']);
# this env flag won't work, it needs to be set in env_base=Environment(MSVC_VERSION='9.0')
# Even then, SCons still seems to ignore it and builds with the latest MSVC...
# That said, it's not needed to be set so far but I'm leaving it here so that this comment
# has a purpose.
# env['MSVS_VERSION']='9.0'
if (env['speex']=='yes'):
env.Append(CPPFLAGS=['-DSPEEX_ENABLED']);
# Calls a CMD with /C(lose) and /V(delayed environment variable expansion) options.
# And runs vcvarsall bat for the propper arhitecture and scons for propper configuration
env['MSVSBUILDCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) ^& call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons platform=windows target=$(Configuration) tools=!tools! -j2'
env['MSVSREBUILDCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) & call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons platform=windows target=$(Configuration) tools=!tools! vsproj=yes -j2'
env['MSVSCLEANCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) ^& call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons --clean platform=windows target=$(Configuration) tools=!tools! -j2'
if (env['tools']=='yes'):
env.Append(CPPFLAGS=['-DTOOLS_ENABLED'])
if (env['disable_3d']=='yes'):
env.Append(CPPFLAGS=['-D_3D_DISABLED'])
if (env['gdscript']=='yes'):
env.Append(CPPFLAGS=['-DGDSCRIPT_ENABLED'])
if (env['disable_advanced_gui']=='yes'):
env.Append(CPPFLAGS=['-DADVANCED_GUI_DISABLED'])
if (env['minizip'] == 'yes'):
env.Append(CPPFLAGS=['-DMINIZIP_ENABLED'])
if (env['xml']=='yes'):
env.Append(CPPFLAGS=['-DXML_ENABLED'])
if (env['colored']=='yes'):
methods.colored(sys,env)
if (env['etc1']=='yes'):
env.Append(CPPFLAGS=['-DETC1_ENABLED'])
Export('env')
#build subdirs, the build order is dependent on link order.
SConscript("core/SCsub")
SConscript("servers/SCsub")
SConscript("scene/SCsub")
SConscript("tools/SCsub")
SConscript("drivers/SCsub")
SConscript("bin/SCsub")
SConscript("modules/SCsub")
SConscript("main/SCsub")
SConscript("platform/"+selected_platform+"/SCsub"); # build selected platform
# Microsoft Visual Studio Project Generation
if (env['vsproj'])=="yes":
AddToVSProject(env.core_sources)
AddToVSProject(env.main_sources)
AddToVSProject(env.modules_sources)
AddToVSProject(env.scene_sources)
AddToVSProject(env.servers_sources)
AddToVSProject(env.tool_sources)
# this env flag won't work, it needs to be set in env_base=Environment(MSVC_VERSION='9.0')
# Even then, SCons still seems to ignore it and builds with the latest MSVC...
# That said, it's not needed to be set so far but I'm leaving it here so that this comment
# has a purpose.
#env['MSVS_VERSION']='9.0'
# Calls a CMD with /C(lose) and /V(delayed environment variable expansion) options.
# And runs vcvarsall bat for the propper arhitecture and scons for propper configuration
env['MSVSBUILDCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) ^& call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons platform=windows target=$(Configuration) tools=!tools! -j2'
env['MSVSREBUILDCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) & call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons platform=windows target=$(Configuration) tools=!tools! vsproj=yes -j2'
env['MSVSCLEANCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) ^& call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons --clean platform=windows target=$(Configuration) tools=!tools! -j2'
# This version information (Win32, x64, Debug, Release, Release_Debug seems to be
# required for Visual Studio to understand that it needs to generate an NMAKE
# project. Do not modify without knowing what you are doing.
debug_variants = ['debug|Win32']+['debug|x64']
release_variants = ['release|Win32']+['release|x64']
release_debug_variants = ['release_debug|Win32']+['release_debug|x64']
variants = debug_variants + release_variants + release_debug_variants
debug_targets = ['Debug']+['Debug']
release_targets = ['Release']+['Release']
release_debug_targets = ['ReleaseDebug']+['ReleaseDebug']
targets = debug_targets + release_targets + release_debug_targets
msvproj = env.MSVSProject(target = ['#godot' + env['MSVSPROJECTSUFFIX'] ],
incs = env.vs_incs,
srcs = env.vs_srcs,
runfile = targets,
buildtarget = targets,
auto_build_solution=1,
variant = variants)
# This version information (Win32, x64, Debug, Release, Release_Debug seems to be
# required for Visual Studio to understand that it needs to generate an NMAKE
# project. Do not modify without knowing what you are doing.
debug_variants = ['debug|Win32'] + ['debug|x64']
release_variants = ['release|Win32'] + ['release|x64']
release_debug_variants = ['release_debug|Win32'] + ['release_debug|x64']
variants = debug_variants + release_variants + release_debug_variants
debug_targets = ['bin\\godot.windows.tools.32.exe'] + ['bin\\godot.windows.tools.64.exe']
release_targets = ['bin\\godot.windows.opt.32.exe'] + ['bin\\godot.windows.opt.64.exe']
release_debug_targets = ['bin\\godot.windows.opt.tools.32.exe'] + ['bin\\godot.windows.opt.tools.64.exe']
targets = debug_targets + release_targets + release_debug_targets
msvproj = env.MSVSProject(target=['#godot' + env['MSVSPROJECTSUFFIX']],
incs=env.vs_incs,
srcs=env.vs_srcs,
runfile=targets,
buildtarget=targets,
auto_build_solution=1,
variant=variants)
else:
print("No valid target platform selected.")
print("The following were detected:")
for x in platform_list:
print("\t"+x)
print("\nPlease run scons again with argument: platform=<string>")
print("No valid target platform selected.")
print("The following were detected:")
for x in platform_list:
print("\t" + x)
print("\nPlease run scons again with argument: platform=<string>")

View File

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

View File

@@ -1,12 +0,0 @@
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])

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,65 +1,68 @@
#!/usr/bin/env python
Import('env')
env.core_sources=[]
env.core_sources = []
gd_call=""
gd_inc=""
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"
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"
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 = 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:
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:
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)
f = open("script_encryption_key.cpp", "wb")
f.write("#include \"globals.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
f.close()
env.add_source_files(env.core_sources,"*.cpp")
env.add_source_files(env.core_sources, "*.cpp")
Export('env')
import make_binders
env.Command(['method_bind.inc','method_bind_ext.inc'], 'make_binders.py', make_binders.run)
env.Command(['method_bind.inc', 'method_bind_ext.inc'], 'make_binders.py', make_binders.run)
SConscript('os/SCsub');
SConscript('math/SCsub');
SConscript('io/SCsub');
SConscript('bind/SCsub');
SConscript('os/SCsub')
SConscript('math/SCsub')
SConscript('io/SCsub')
SConscript('bind/SCsub')
SConscript('helper/SCsub')
lib = env.Library("core",env.core_sources)
lib = env.Library("core", env.core_sources)
env.Prepend(LIBS=[lib])

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -30,13 +31,13 @@
#define ALLOCATORS_H
#include "os/memory.h"
template<int PREALLOC_COUNT=64, int MAX_HANDS=8>
template <int PREALLOC_COUNT = 64, int MAX_HANDS = 8>
class BalloonAllocator {
enum {
USED_FLAG=(1<<30),
USED_MASK=USED_FLAG-1
USED_FLAG = (1 << 30),
USED_MASK = USED_FLAG - 1
};
struct Balloon {
@@ -46,7 +47,6 @@ class BalloonAllocator {
uint32_t hand;
};
struct Hand {
int used;
@@ -55,136 +55,132 @@ class BalloonAllocator {
Balloon *last;
};
Hand hands[MAX_HANDS];
public:
void *alloc(size_t p_size) {
void* alloc(size_t p_size) {
size_t max = (1 << MAX_HANDS);
ERR_FAIL_COND_V(p_size > max, NULL);
size_t max=(1<<MAX_HANDS);
ERR_FAIL_COND_V( p_size>max, NULL );
unsigned int hand = 0;
unsigned int hand=0;
while (p_size > (size_t)(1 << hand))
++hand;
while(p_size>(size_t)(1<<hand)) ++hand;
Hand &h = hands[hand];
Hand &h=hands[hand];
if (h.used == h.allocated) {
if (h.used==h.allocated) {
for (int i = 0; i < PREALLOC_COUNT; i++) {
for(int i=0;i<PREALLOC_COUNT;i++) {
Balloon *b = (Balloon*)memalloc(sizeof(Balloon)+(1<<hand));
b->hand=hand;
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;
b->prev = h.last;
h.last->next = b;
h.last = b;
} else {
b->prev=NULL;
h.last=b;
h.first=b;
b->prev = NULL;
h.last = b;
h.first = b;
}
}
h.last->next=NULL;
h.allocated+=PREALLOC_COUNT;
h.last->next = NULL;
h.allocated += PREALLOC_COUNT;
}
Balloon *pick=h.last;
Balloon *pick = h.last;
ERR_FAIL_COND_V( (pick->hand&USED_FLAG), NULL );
ERR_FAIL_COND_V((pick->hand & USED_FLAG), NULL);
// remove last
h.last=h.last->prev;
h.last->next=NULL;
h.last = h.last->prev;
h.last->next = NULL;
pick->next=h.first;
h.first->prev=pick;
pick->prev=NULL;
h.first=pick;
pick->next = h.first;
h.first->prev = pick;
pick->prev = NULL;
h.first = pick;
h.used++;
pick->hand|=USED_FLAG;
pick->hand |= USED_FLAG;
return (void*)(pick+1);
return (void *)(pick + 1);
}
void free(void* p_ptr) {
void free(void *p_ptr) {
Balloon *b=(Balloon*)p_ptr;
b-=1;
Balloon *b = (Balloon *)p_ptr;
b -= 1;
ERR_FAIL_COND(!(b->hand&USED_FLAG) );
ERR_FAIL_COND(!(b->hand & USED_FLAG));
b->hand=b->hand&USED_MASK; // not used
int hand=b->hand;
b->hand = b->hand & USED_MASK; // not used
int hand = b->hand;
Hand &h=hands[hand];
Hand &h = hands[hand];
if (b==h.first)
h.first=b->next;
if (b == h.first)
h.first = b->next;
if (b->prev)
b->prev->next=b->next;
b->prev->next = b->next;
if (b->next)
b->next->prev=b->prev;
b->next->prev = b->prev;
if (h.last!=b) {
h.last->next=b;
b->prev=h.last;
b->next=NULL;
h.last=b;
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
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 );
for (int i = 0; i < PREALLOC_COUNT; i++) {
ERR_CONTINUE(h.last->hand & USED_FLAG);
Balloon *new_last=h.last->prev;
Balloon *new_last = h.last->prev;
if (new_last)
new_last->next=NULL;
memfree( h.last );
h.last=new_last;
new_last->next = NULL;
memfree(h.last);
h.last = new_last;
}
h.allocated-=PREALLOC_COUNT;
h.allocated -= PREALLOC_COUNT;
}
}
BalloonAllocator() {
for(int i=0;i<MAX_HANDS;i++) {
for (int i = 0; i < MAX_HANDS; i++) {
hands[i].allocated=0;
hands[i].used=0;
hands[i].first=NULL;
hands[i].last=NULL;
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++) {
for (int i = 0; i < MAX_HANDS; i++) {
while(hands[i].first) {
while (hands[i].first) {
Balloon *b=hands[i].first;
hands[i].first=b->next;
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;
hands[i].allocated = 0;
hands[i].used = 0;
hands[i].first = NULL;
hands[i].last = NULL;
}
}
@@ -194,5 +190,4 @@ public:
}
};
#endif // ALLOCATORS_H

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -27,10 +28,10 @@
/* 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 "variant.h"
#include "vector.h"
struct ArrayPrivate {
@@ -39,7 +40,7 @@ struct ArrayPrivate {
bool shared;
};
void Array::_ref(const Array& p_from) const {
void Array::_ref(const Array &p_from) const {
ArrayPrivate *_fp = p_from._p;
@@ -60,10 +61,10 @@ void Array::_ref(const Array& p_from) const {
} else {
_p = memnew( ArrayPrivate );
_p->shared=false;
_p = memnew(ArrayPrivate);
_p->shared = false;
_p->refcount.init();
_p->array=_fp->array;
_p->array = _fp->array;
if (_fp->refcount.unref())
memdelete(_fp);
@@ -78,19 +79,17 @@ void Array::_unref() const {
if (_p->refcount.unref()) {
memdelete(_p);
}
_p=NULL;
_p = NULL;
}
Variant& Array::operator[](int p_idx) {
Variant &Array::operator[](int p_idx) {
return _p->array[p_idx];
}
const Variant& Array::operator[](int p_idx) const {
const Variant &Array::operator[](int p_idx) const {
return _p->array[p_idx];
}
int Array::size() const {
@@ -108,29 +107,29 @@ void Array::clear() {
bool Array::is_shared() const {
return _p->shared;
return _p->shared;
}
bool Array::operator==(const Array& p_array) const {
bool Array::operator==(const Array &p_array) const {
return _p==p_array._p;
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);
}
@@ -140,22 +139,32 @@ 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);
}
int Array::find(const Variant& p_value, int p_from) const {
Variant Array::front() const {
ERR_FAIL_COND_V(_p->array.size() == 0, Variant());
return operator[](0);
}
Variant Array::back() const {
ERR_FAIL_COND_V(_p->array.size() == 0, Variant());
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 {
int Array::rfind(const Variant &p_value, int p_from) const {
if (_p->array.size() == 0)
return -1;
@@ -169,9 +178,9 @@ int Array::rfind(const Variant& p_value, int p_from) const {
p_from = _p->array.size() - 1;
}
for (int i=p_from; i>=0; i--) {
for (int i = p_from; i >= 0; i--) {
if(_p->array[i] == p_value){
if (_p->array[i] == p_value) {
return i;
};
};
@@ -179,20 +188,20 @@ int Array::rfind(const Variant& p_value, int p_from) const {
return -1;
}
int Array::find_last(const Variant& p_value) const {
int Array::find_last(const Variant &p_value) const {
return rfind(p_value);
}
int Array::count(const Variant& p_value) const {
int Array::count(const Variant &p_value) const {
if(_p->array.size() == 0)
if (_p->array.size() == 0)
return 0;
int amount=0;
for (int i=0; i<_p->array.size(); i++) {
int amount = 0;
for (int i = 0; i < _p->array.size(); i++) {
if(_p->array[i] == p_value){
if (_p->array[i] == p_value) {
amount++;
};
};
@@ -200,7 +209,7 @@ int Array::count(const Variant& p_value) const {
return amount;
}
bool Array::has(const Variant& p_value) const {
bool Array::has(const Variant &p_value) const {
return _p->array.find(p_value, 0) != -1;
}
@@ -209,25 +218,24 @@ void Array::remove(int p_pos) {
_p->array.remove(p_pos);
}
void Array::set(int p_idx, const Variant &p_value) {
void Array::set(int p_idx,const Variant& p_value) {
operator[](p_idx)=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);
}
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;
}
};
@@ -235,7 +243,6 @@ struct _ArrayVariantSort {
void Array::sort() {
_p->array.sort_custom<_ArrayVariantSort>();
}
struct _ArrayVariantSortCustom {
@@ -243,64 +250,57 @@ 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;
}
};
void Array::sort_custom(Object *p_obj,const StringName& p_function){
void Array::sort_custom(Object *p_obj, const StringName &p_function) {
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> avs;
avs.compare.obj = p_obj;
avs.compare.func = p_function;
avs.sort(_p->array.ptr(), _p->array.size());
}
void Array::invert(){
void Array::invert() {
_p->array.invert();
}
void Array::push_front(const Variant &p_value) {
void Array::push_front(const Variant& p_value) {
_p->array.insert(0,p_value);
_p->array.insert(0, p_value);
}
void Array::pop_back(){
void Array::pop_back() {
if (!_p->array.empty())
_p->array.resize( _p->array.size() -1 );
_p->array.resize(_p->array.size() - 1);
}
void Array::pop_front(){
void Array::pop_front() {
if (!_p->array.empty())
_p->array.remove(0);
}
Array::Array(const Array &p_from) {
Array::Array(const Array& p_from) {
_p=NULL;
_p = NULL;
_ref(p_from);
}
Array::Array(bool p_shared) {
_p = memnew( ArrayPrivate );
_p = memnew(ArrayPrivate);
_p->refcount.init();
_p->shared=p_shared;
_p->shared = p_shared;
}
Array::~Array() {

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -38,16 +39,15 @@ class StringName;
class Array {
mutable ArrayPrivate *_p;
void _ref(const Array& p_from) const;
void _ref(const Array &p_from) const;
void _unref() const;
public:
Variant &operator[](int p_idx);
const Variant &operator[](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;
void set(int p_idx, const Variant &p_value);
const Variant &get(int p_idx) const;
int size() const;
bool empty() const;
@@ -55,38 +55,40 @@ public:
bool is_shared() const;
bool operator==(const Array& p_array) 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 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 sort_custom(Object *p_obj, const StringName &p_function);
void invert();
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;
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);
void push_front(const Variant &p_value);
void pop_back();
void pop_front();
Array(const Array& p_from);
Array(bool p_shared=false);
Array(const Array &p_from);
Array(bool p_shared = false);
~Array();
};
#endif // ARRAY_H

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,73 +32,67 @@
#include "io/resource_loader.h"
#include "io/resource_saver.h"
#include "os/file_access.h"
#include "os/dir_access.h"
#include "os/thread.h"
#include "os/file_access.h"
#include "os/semaphore.h"
#include "os/thread.h"
class _ResourceLoader : public Object {
OBJ_TYPE(_ResourceLoader,Object);
class _ResourceLoader : public Object {
OBJ_TYPE(_ResourceLoader, Object);
protected:
static void _bind_methods();
static _ResourceLoader *singleton;
public:
static _ResourceLoader *get_singleton() { return singleton; }
Ref<ResourceInteractiveLoader> load_interactive(const String& p_path,const String& p_type_hint="");
RES load(const String &p_path,const String& p_type_hint="", bool p_no_cache = false);
DVector<String> get_recognized_extensions_for_type(const String& p_type);
Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "");
RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false);
DVector<String> get_recognized_extensions_for_type(const String &p_type);
void set_abort_on_missing_resources(bool p_abort);
StringArray get_dependencies(const String& p_path);
bool has(const String& p_path);
Ref<ResourceImportMetadata> load_import_metadata(const String& p_path);
StringArray get_dependencies(const String &p_path);
bool has(const String &p_path);
Ref<ResourceImportMetadata> load_import_metadata(const String &p_path);
_ResourceLoader();
};
class _ResourceSaver : public Object {
OBJ_TYPE(_ResourceSaver,Object);
class _ResourceSaver : public Object {
OBJ_TYPE(_ResourceSaver, Object);
protected:
static void _bind_methods();
static _ResourceSaver *singleton;
public:
public:
enum SaverFlags {
FLAG_RELATIVE_PATHS=1,
FLAG_BUNDLE_RESOURCES=2,
FLAG_CHANGE_PATH=4,
FLAG_OMIT_EDITOR_PROPERTIES=8,
FLAG_SAVE_BIG_ENDIAN=16,
FLAG_COMPRESS=32,
FLAG_RELATIVE_PATHS = 1,
FLAG_BUNDLE_RESOURCES = 2,
FLAG_CHANGE_PATH = 4,
FLAG_OMIT_EDITOR_PROPERTIES = 8,
FLAG_SAVE_BIG_ENDIAN = 16,
FLAG_COMPRESS = 32,
};
static _ResourceSaver *get_singleton() { return singleton; }
Error save(const String &p_path,const RES& p_resource, uint32_t p_flags);
DVector<String> get_recognized_extensions(const RES& p_resource);
Error save(const String &p_path, const RES &p_resource, uint32_t p_flags);
DVector<String> get_recognized_extensions(const RES &p_resource);
_ResourceSaver();
};
class MainLoop;
class _OS : public Object {
OBJ_TYPE(_OS,Object);
class _OS : public Object {
OBJ_TYPE(_OS, Object);
protected:
static void _bind_methods();
static _OS *singleton;
public:
public:
enum Weekday {
DAY_SUNDAY,
DAY_MONDAY,
@@ -126,30 +121,28 @@ public:
};
Point2 get_mouse_pos() const;
void set_window_title(const String& p_title);
void set_window_title(const String &p_title);
int get_mouse_button_state() const;
void set_clipboard(const String& p_text);
void set_clipboard(const String &p_text);
String get_clipboard() const;
void set_video_mode(const Size2& p_size, bool p_fullscreen,bool p_resizeable,int p_screen=0);
Size2 get_video_mode(int p_screen=0) const;
bool is_video_mode_fullscreen(int p_screen=0) const;
bool is_video_mode_resizable(int p_screen=0) const;
Array get_fullscreen_mode_list(int p_screen=0) const;
void set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen = 0);
Size2 get_video_mode(int p_screen = 0) const;
bool is_video_mode_fullscreen(int p_screen = 0) const;
bool is_video_mode_resizable(int p_screen = 0) const;
Array get_fullscreen_mode_list(int p_screen = 0) const;
virtual int get_screen_count() const;
virtual int get_current_screen() const;
virtual void set_current_screen(int p_screen);
virtual Point2 get_screen_position(int p_screen=0) const;
virtual Size2 get_screen_size(int p_screen=0) const;
virtual int get_screen_dpi(int p_screen=0) const;
virtual Point2 get_screen_position(int p_screen = 0) const;
virtual Size2 get_screen_size(int p_screen = 0) const;
virtual int get_screen_dpi(int p_screen = 0) const;
virtual Point2 get_window_position() const;
virtual void set_window_position(const Point2& p_position);
virtual void set_window_position(const Point2 &p_position);
virtual Size2 get_window_size() const;
virtual void set_window_size(const Size2& p_size);
virtual void set_window_size(const Size2 &p_size);
virtual void set_window_fullscreen(bool p_enabled);
virtual bool is_window_fullscreen() const;
virtual void set_window_resizable(bool p_enabled);
@@ -179,15 +172,15 @@ public:
bool is_in_low_processor_usage_mode() const;
String get_executable_path() const;
int execute(const String& p_path, const Vector<String> & p_arguments,bool p_blocking,Array p_output=Array());
int execute(const String &p_path, const Vector<String> &p_arguments, bool p_blocking, Array p_output = Array());
Error kill(int p_pid);
Error shell_open(String p_uri);
int get_process_ID() const;
bool has_environment(const String& p_var) const;
String get_environment(const String& p_var) const;
bool has_environment(const String &p_var) const;
String get_environment(const String &p_var) const;
String get_name() const;
Vector<String> get_cmdline_args();
@@ -202,17 +195,17 @@ public:
float get_frames_per_second() const;
void dump_memory_to_file(const String& p_file);
void dump_resources_to_file(const String& p_file);
void dump_memory_to_file(const String &p_file);
void dump_resources_to_file(const String &p_file);
bool has_virtual_keyboard() const;
void show_virtual_keyboard(const String& p_existing_text="");
void show_virtual_keyboard(const String &p_existing_text = "");
void hide_virtual_keyboard();
void print_resources_in_use(bool p_short=false);
void print_all_resources(const String& p_to_file);
void print_resources_in_use(bool p_short = false);
void print_all_resources(const String &p_to_file);
void print_all_textures_by_size();
void print_resources_by_type(const Vector<String>& p_types);
void print_resources_by_type(const Vector<String> &p_types);
bool has_touchscreen_ui_hint() const;
@@ -222,8 +215,7 @@ public:
String get_scancode_string(uint32_t p_code) const;
bool is_scancode_unicode(uint32_t p_unicode) const;
int find_scancode_from_string(const String& p_code) const;
int find_scancode_from_string(const String &p_code) const;
/*
struct Date {
@@ -245,7 +237,10 @@ public:
void set_use_file_access_save_and_swap(bool p_enable);
void set_icon(const Image& p_icon);
void set_icon(const Image &p_icon);
int get_exit_code() const;
void set_exit_code(int p_code);
Dictionary get_date(bool utc) const;
Dictionary get_time(bool utc) const;
Dictionary get_datetime(bool utc) const;
@@ -268,7 +263,7 @@ public:
bool can_draw() const;
int get_frames_drawn();
int get_frames_drawn();
bool is_stdout_verbose() const;
@@ -298,11 +293,9 @@ public:
String get_system_dir(SystemDir p_dir) const;
String get_data_dir() const;
void alert(const String& p_alert,const String& p_title="ALERT!");
void alert(const String &p_alert, const String &p_title = "ALERT!");
void set_screen_orientation(ScreenOrientation p_orientation);
ScreenOrientation get_screen_orientation() const;
@@ -315,10 +308,10 @@ public:
bool is_ok_left_and_cancel_right() const;
Error set_thread_name(const String& p_name);
Error set_thread_name(const String &p_name);
void set_use_vsync(bool p_enable);
bool is_vsnc_enabled() const;
bool is_vsync_enabled() const;
Dictionary get_engine_version() const;
@@ -330,73 +323,71 @@ public:
VARIANT_ENUM_CAST(_OS::SystemDir);
VARIANT_ENUM_CAST(_OS::ScreenOrientation);
class _Geometry : public Object {
OBJ_TYPE(_Geometry, Object);
static _Geometry *singleton;
protected:
static void _bind_methods();
public:
static _Geometry *get_singleton();
DVector<Plane> build_box_planes(const Vector3& p_extents);
DVector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis=Vector3::AXIS_Z);
DVector<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis=Vector3::AXIS_Z);
Variant segment_intersects_segment_2d(const Vector2& p_from_a,const Vector2& p_to_a,const Vector2& p_from_b,const Vector2& p_to_b);
DVector<Vector2> get_closest_points_between_segments_2d( const Vector2& p1,const Vector2& q1, const Vector2& p2,const Vector2& q2);
DVector<Vector3> get_closest_points_between_segments(const Vector3& p1,const Vector3& p2,const Vector3& q1,const Vector3& q2);
Vector3 get_closest_point_to_segment(const Vector3& p_point, const Vector3& p_a,const Vector3& p_b);
Variant ray_intersects_triangle( const Vector3& p_from, const Vector3& p_dir, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2);
Variant segment_intersects_triangle( const Vector3& p_from, const Vector3& p_to, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2);
bool point_is_inside_triangle(const Vector2& s, const Vector2& a, const Vector2& b, const Vector2& c) const;
DVector<Plane> build_box_planes(const Vector3 &p_extents);
DVector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
DVector<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z);
Variant segment_intersects_segment_2d(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b);
DVector<Vector2> get_closest_points_between_segments_2d(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2);
DVector<Vector3> get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2);
Vector2 get_closest_point_to_segment_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b);
Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b);
Variant ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
Variant segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
bool point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const;
DVector<Vector3> segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius);
DVector<Vector3> segment_intersects_cylinder( const Vector3& p_from, const Vector3& p_to, float p_height,float p_radius);
DVector<Vector3> segment_intersects_convex(const Vector3& p_from, const Vector3& p_to,const Vector<Plane>& p_planes);
real_t segment_intersects_circle(const Vector2& p_from, const Vector2& p_to, const Vector2& p_circle_pos, real_t p_circle_radius);
int get_uv84_normal_bit(const Vector3& p_vector);
DVector<Vector3> segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius);
DVector<Vector3> segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius);
DVector<Vector3> segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes);
real_t segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius);
int get_uv84_normal_bit(const Vector3 &p_vector);
Vector<int> triangulate_polygon(const Vector<Vector2>& p_polygon);
Vector<int> triangulate_polygon(const Vector<Vector2> &p_polygon);
Dictionary make_atlas(const Vector<Size2>& p_rects);
Dictionary make_atlas(const Vector<Size2> &p_rects);
_Geometry();
};
class _File : public Reference {
OBJ_TYPE(_File,Reference);
OBJ_TYPE(_File, Reference);
FileAccess *f;
bool eswap;
protected:
static void _bind_methods();
public:
enum ModeFlags {
enum ModeFlags {
READ=1,
WRITE=2,
READ_WRITE=3,
WRITE_READ=7,
READ = 1,
WRITE = 2,
READ_WRITE = 3,
WRITE_READ = 7,
};
Error open_encrypted(const String& p_path, int p_mode_flags,const Vector<uint8_t>& p_key);
Error open_encrypted_pass(const String& p_path, int p_mode_flags,const String& p_pass);
Error open_encrypted(const String &p_path, int p_mode_flags, const Vector<uint8_t> &p_key);
Error open_encrypted_pass(const String &p_path, int p_mode_flags, const String &p_pass);
Error open(const String& p_path, int p_mode_flags); ///< open a file
Error open(const String &p_path, int p_mode_flags); ///< open a file
void close(); ///< close a file
bool is_open() const; ///< true when file is open
void seek(int64_t p_position); ///< seek to a given position
void seek_end(int64_t p_position=0); ///< seek from the end of file
void seek_end(int64_t p_position = 0); ///< seek from the end of file
int64_t get_pos() const; ///< get position in the file
int64_t get_len() const; ///< get size of the file
@@ -416,8 +407,8 @@ public:
DVector<uint8_t> get_buffer(int p_length) const; ///< get an array of bytes
String get_line() const;
String get_as_text() const;
String get_md5(const String& p_path) const;
String get_sha256(const String& p_path) const;
String get_md5(const String &p_path) const;
String get_sha256(const String &p_path) const;
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
* It's not about the current CPU type but file formats.
@@ -438,36 +429,36 @@ public:
void store_double(double p_dest);
void store_real(real_t p_real);
void store_string(const String& p_string);
void store_line(const String& p_string);
void store_string(const String &p_string);
void store_line(const String &p_string);
virtual void store_pascal_string(const String& p_string);
virtual void store_pascal_string(const String &p_string);
virtual String get_pascal_string();
Vector<String> get_csv_line(String delim=",") const;
Vector<String> get_csv_line(String delim = ",") const;
void store_buffer(const DVector<uint8_t> &p_buffer); ///< store an array of bytes
void store_buffer(const DVector<uint8_t>& p_buffer); ///< store an array of bytes
void store_var(const Variant &p_var);
void store_var(const Variant& p_var);
bool file_exists(const String &p_name) const; ///< return true if a file exists
bool file_exists(const String& p_name) const; ///< return true if a file exists
uint64_t get_modified_time(const String &p_file) const;
_File();
virtual ~_File();
};
class _Directory : public Reference {
OBJ_TYPE(_Directory,Reference);
OBJ_TYPE(_Directory, Reference);
DirAccess *d;
protected:
static void _bind_methods();
public:
Error open(const String& p_path);
public:
Error open(const String &p_path);
bool list_dir_begin(); ///< This starts dir listing
String get_next();
@@ -489,48 +480,42 @@ public:
int get_space_left();
Error copy(String p_from,String p_to);
Error copy(String p_from, String p_to);
Error rename(String p_from, String p_to);
Error remove(String p_name);
_Directory();
virtual ~_Directory();
};
class _Marshalls : public Reference {
OBJ_TYPE(_Marshalls,Reference);
OBJ_TYPE(_Marshalls, Reference);
protected:
static void _bind_methods();
public:
String variant_to_base64(const Variant &p_var);
Variant base64_to_variant(const String &p_str);
String variant_to_base64(const Variant& p_var);
Variant base64_to_variant(const String& p_str);
String raw_to_base64(const DVector<uint8_t> &p_arr);
DVector<uint8_t> base64_to_raw(const String &p_str);
String raw_to_base64(const DVector<uint8_t>& p_arr);
DVector<uint8_t> base64_to_raw(const String& p_str);
String utf8_to_base64(const String &p_str);
String base64_to_utf8(const String &p_str);
String utf8_to_base64(const String& p_str);
String base64_to_utf8(const String& p_str);
_Marshalls() {};
_Marshalls(){};
};
class _Mutex : public Reference {
OBJ_TYPE(_Mutex,Reference);
OBJ_TYPE(_Mutex, Reference);
Mutex *mutex;
static void _bind_methods();
public:
public:
void lock();
Error try_lock();
void unlock();
@@ -541,12 +526,12 @@ public:
class _Semaphore : public Reference {
OBJ_TYPE(_Semaphore,Reference);
OBJ_TYPE(_Semaphore, Reference);
Semaphore *semaphore;
static void _bind_methods();
public:
public:
Error wait();
Error post();
@@ -556,10 +541,9 @@ public:
class _Thread : public Reference {
OBJ_TYPE(_Thread,Reference);
OBJ_TYPE(_Thread, Reference);
protected:
Variant ret;
Variant userdata;
volatile bool active;
@@ -568,8 +552,8 @@ protected:
Thread *thread;
static void _bind_methods();
static void _start_func(void *ud);
public:
public:
enum Priority {
PRIORITY_LOW,
@@ -577,7 +561,7 @@ public:
PRIORITY_HIGH
};
Error start(Object *p_instance,const StringName& p_method,const Variant& p_userdata=Variant(),int p_priority=PRIORITY_NORMAL);
Error start(Object *p_instance, const StringName &p_method, const Variant &p_userdata = Variant(), int p_priority = PRIORITY_NORMAL);
String get_id() const;
bool is_active() const;
Variant wait_to_finish();

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -27,80 +28,80 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "color.h"
#include "color_names.inc"
#include "map.h"
#include "math_funcs.h"
#include "print_string.h"
uint32_t Color::to_ARGB32() const {
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);
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_32() const {
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);
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 = 4 + (r - g) / delta; // between magenta & cyan
h/=6.0;
if (h<0)
h+=1.0;
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;
}
@@ -108,24 +109,24 @@ 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;
p_h = Math::fmod(p_h, 6);
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 ) {
switch (i) {
case 0: // Red is the dominant color
r = p_v;
g = t;
@@ -161,219 +162,228 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
void Color::invert() {
r=1.0-r;
g=1.0-g;
b=1.0-b;
r = 1.0 - r;
g = 1.0 - g;
b = 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);
}
static float _parse_col(const String& p_str, int p_ofs) {
static float _parse_col(const String &p_str, int p_ofs) {
int ig=0;
int ig = 0;
for(int i=0;i<2;i++) {
for (int i = 0; i < 2; i++) {
int c=p_str[i+p_ofs];
int v=0;
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[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_EXPLAIN("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);
if (a<0) {
ERR_EXPLAIN("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);
if (r<0) {
ERR_EXPLAIN("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);
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);
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;
int a = 255;
if (alpha) {
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);
if (color) {
return color->value();
} else {
ERR_EXPLAIN("Invalid Color Name: " + p_name);
ERR_FAIL_V(Color());
}
}
String _to_hex(float p_val) {
int v = p_val * 255;
v = CLAMP(v,0,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;
}
float Color::gray() const {
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);
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,8 +30,8 @@
#ifndef COLOR_H
#define COLOR_H
#include "ustring.h"
#include "math_funcs.h"
#include "ustring.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -47,8 +48,8 @@ struct Color {
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_32() const;
uint32_t to_ARGB32() const;
@@ -56,12 +57,12 @@ struct Color {
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];
}
@@ -70,30 +71,29 @@ struct Color {
Color inverted() const;
Color contrasted() const;
_FORCE_INLINE_ Color linear_interpolate(const Color& p_b, float p_t) const {
_FORCE_INLINE_ Color linear_interpolate(const Color &p_b, float p_t) const {
Color res=*this;
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));
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 blend(const Color& p_over) const {
_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;
}
@@ -101,47 +101,54 @@ 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
);
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 html(const String& p_color);
static bool html_is_valid(const String& p_color);
String to_html(bool p_alpha=true) const;
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;
_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

152
core/color_names.inc Normal file
View File

@@ -0,0 +1,152 @@
// Names from https://en.wikipedia.org/wiki/List_of_colors (through https://raw.githubusercontent.com/SuperUserNameMan/color_to_name/616a7cddafefda91478b7bc26167de97fb5badb1/godot_version.gd), slightly edited and normalized
#include "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("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

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -47,22 +48,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) {
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;
}
}
if (idx==-1) {
if (idx == -1) {
wait_for_flush();
} else {
break;
@@ -72,36 +73,30 @@ CommandQueueMT::SyncSemaphore* CommandQueueMT::_alloc_sync_sem() {
return &sync_sems[idx];
}
CommandQueueMT::CommandQueueMT(bool p_sync) {
CommandQueueMT::CommandQueueMT(bool p_sync){
read_ptr=0;
write_ptr=0;
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;
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
sync_sems[i].sem = Semaphore::create();
sync_sems[i].in_use = false;
}
if (p_sync)
sync = Semaphore::create();
else
sync=NULL;
sync = NULL;
}
CommandQueueMT::~CommandQueueMT() {
if (sync)
memdelete(sync);
memdelete(mutex);
for(int i=0;i<SYNC_SEMAPHORES;i++) {
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

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -45,201 +46,199 @@ Redistribution and use in source and binary forms, with or without modification,
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"
"\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"
" ", "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;
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;
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;
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
/* 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,
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;
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;
}
/* 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;
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;
}
}
}
/* 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;
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;
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);
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--;
if (outlen < len) return _outlen + 1;
memcpy(out, s, len);
out += len;
outlen -= len;
c++;
inlen--;
}
}
}
return out-_out;
return out - _out;
}
/////////// END OF SMAZ /////////////
struct _PHashTranslationCmp {
@@ -254,104 +253,100 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
List<StringName> keys;
p_from->get_message_list(&keys);
int size=Math::larger_prime(keys.size());
int size = Math::larger_prime(keys.size());
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;
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;
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[0],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[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;
print_line("total compressed string size: "+itos(total_compression_size)+" ("+itos(total_string_size)+" uncompressed).");
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++) {
Vector< Pair<int,CharString> > &b = buckets[i];
Map< uint32_t, int > &t=table[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[i]=d;
bucket_table_size+=2+b.size()*4;
hfunc_table[i] = d;
bucket_table_size += 2 + b.size() * 4;
}
print_line("bucket table size: "+itos(bucket_table_size*4));
print_line("hash table size: "+itos(size*4));
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);
@@ -359,176 +354,166 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
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++) {
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));
print_line("total collisions: " + itos(collisions));
strings.resize(total_compression_size);
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;
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;
} 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;
} else if (name == "strings") {
strings = p_value;
//print_line("translation: loaded string table of size: "+itos(strings.size()));
} else if (name=="load_from") {
} 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());
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<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];
const char *sptr = (const char *)&sr[0];
uint32_t p = htptr[ h % htsize];
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!");
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;
}
}
//print_line("bucket pos: "+itos(idx));
if (idx==-1) {
// print_line("GETMSG: Not in Bucket!");
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 );
// print_line("Uncompressed, size: "+itos(bucket.elem[idx].comp_size));
// print_line("Return: "+rstr);
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.ptr(),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);
// 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 {
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));
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() {
ObjectTypeDB::bind_method(_MD("generate","from:Translation"),&PHashTranslation::generate);
ObjectTypeDB::bind_method(_MD("generate", "from:Translation"), &PHashTranslation::generate);
}
PHashTranslation::PHashTranslation()
{
PHashTranslation::PHashTranslation() {
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -33,8 +34,7 @@
class PHashTranslation : public Translation {
OBJ_TYPE(PHashTranslation,Translation);
OBJ_TYPE(PHashTranslation, Translation);
//this translation uses a sort of modified perfect hash algorithm
//it requieres hashing strings twice and then does a binary search,
@@ -46,7 +46,6 @@ class PHashTranslation : public Translation {
DVector<int> bucket_table;
DVector<uint8_t> strings;
struct Bucket {
int size;
@@ -63,11 +62,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,16 +74,15 @@ 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;
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;
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

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -28,21 +29,19 @@
/*************************************************************************/
#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");
_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");
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -33,18 +34,21 @@
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 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; }
public:
_FORCE_INLINE_ static CoreStringNames *get_singleton() { return singleton; }
StringName _free;
StringName changed;
@@ -57,7 +61,6 @@ public:
StringName _iter_next;
StringName _iter_get;
StringName get_rid;
};
#endif // SCENE_STRING_NAMES_H

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -27,26 +28,23 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "dictionary.h"
#include "io/json.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(); }
static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); }
};
struct DictionaryPrivate {
SafeRefCount refcount;
HashMap<Variant,Variant,_DictionaryVariantHash> variant_map;
HashMap<Variant, Variant, _DictionaryVariantHash> variant_map;
bool shared;
};
void Dictionary::get_key_list( List<Variant> *p_keys) const {
void Dictionary::get_key_list(List<Variant> *p_keys) const {
_p->variant_map.get_key_list(p_keys);
}
@@ -58,36 +56,35 @@ void Dictionary::_copy_on_write() const {
return;
DictionaryPrivate *p = memnew(DictionaryPrivate);
p->shared=_p->shared;
p->variant_map=_p->variant_map;
p->shared = _p->shared;
p->variant_map = _p->variant_map;
p->refcount.init();
_unref();
_p=p;
_p = p;
}
Variant& Dictionary::operator[](const Variant& p_key) {
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 {
return _p->variant_map.getptr(p_key);
}
Variant* Dictionary::getptr(const Variant& p_key) {
Variant *Dictionary::getptr(const Variant &p_key) {
_copy_on_write();
return _p->variant_map.getptr(p_key);
}
Variant Dictionary::get_valid(const Variant& p_key) const {
Variant Dictionary::get_valid(const Variant &p_key) const {
const Variant *v = getptr(p_key);
if (!v)
@@ -95,56 +92,53 @@ Variant Dictionary::get_valid(const Variant& p_key) const {
return *v;
}
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]) ) {
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) {
void Dictionary::erase(const Variant &p_key) {
_copy_on_write();
_p->variant_map.erase(p_key);
}
bool Dictionary::operator==(const Dictionary& p_dictionary) const {
bool Dictionary::operator==(const Dictionary &p_dictionary) const {
return _p==p_dictionary._p;
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() {
@@ -155,34 +149,30 @@ void Dictionary::clear() {
bool Dictionary::is_shared() const {
return _p->shared;
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);
uint32_t h = hash_djb2_one_32(Variant::DICTIONARY);
List<Variant> keys;
get_key_list(&keys);
for (List<Variant>::Element *E=keys.front();E;E=E->next()) {
h = hash_djb2_one_32( E->get().hash(), h);
h = hash_djb2_one_32( operator[](E->get()).hash(), h);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
h = hash_djb2_one_32(E->get().hash(), h);
h = hash_djb2_one_32(operator[](E->get()).hash(), h);
}
return h;
}
@@ -190,42 +180,40 @@ Array Dictionary::keys() const {
Array karr;
karr.resize(size());
const Variant *K=NULL;
int idx=0;
while((K=next(K))) {
karr[idx++]=(*K);
const Variant *K = NULL;
int idx = 0;
while ((K = next(K))) {
karr[idx++] = (*K);
}
return karr;
}
Array Dictionary::values() const {
Array varr;
varr.resize(size());
const Variant *key=NULL;
int i=0;
while((key=next(key))){
const Variant *key = NULL;
int i = 0;
while ((key = next(key))) {
varr[i++] = _p->variant_map[*key];
}
return varr;
}
const Variant* Dictionary::next(const Variant* p_key) const {
const Variant *Dictionary::next(const Variant *p_key) const {
return _p->variant_map.next(p_key);
}
Error Dictionary::parse_json(const String& p_json) {
Error Dictionary::parse_json(const String &p_json) {
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);
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);
}
}
@@ -237,26 +225,21 @@ String Dictionary::to_json() const {
return JSON::print(*this);
}
void Dictionary::operator=(const Dictionary& p_dictionary) {
void Dictionary::operator=(const Dictionary &p_dictionary) {
_ref(p_dictionary);
}
Dictionary::Dictionary(const Dictionary& p_from) {
_p=NULL;
Dictionary::Dictionary(const Dictionary &p_from) {
_p = NULL;
_ref(p_from);
}
Dictionary::Dictionary(bool p_shared) {
_p=memnew( DictionaryPrivate );
_p = memnew(DictionaryPrivate);
_p->refcount.init();
_p->shared=p_shared;
_p->shared = p_shared;
}
Dictionary::~Dictionary() {

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,62 +30,58 @@
#ifndef DICTIONARY_H
#define DICTIONARY_H
#include "list.h"
#include "array.h"
#include "list.h"
#include "ustring.h"
class Variant;
struct DictionaryPrivate;
class Dictionary {
mutable DictionaryPrivate *_p;
void _copy_on_write() const;
void _ref(const Dictionary& p_from) const;
void _ref(const Dictionary &p_from) const;
void _unref() const;
public:
void get_key_list(List<Variant> *p_keys) const;
void get_key_list( List<Variant> *p_keys) const;
Variant &operator[](const Variant &p_key);
const Variant &operator[](const Variant &p_key) const;
Variant& operator[](const Variant& p_key);
const Variant& operator[](const Variant& p_key) const;
const Variant *getptr(const Variant &p_key) const;
Variant *getptr(const Variant &p_key);
const Variant* getptr(const Variant& p_key) const;
Variant* getptr(const Variant& p_key);
Variant get_valid(const Variant& p_key) const;
Variant get_valid(const Variant &p_key) const;
int size() const;
bool empty() const;
void clear();
Error parse_json(const String& p_json);
Error parse_json(const String &p_json);
String to_json() const;
bool is_shared() const;
bool has(const Variant& p_key) const;
bool has_all(const Array& p_keys) const;
bool has(const Variant &p_key) const;
bool has_all(const Array &p_keys) const;
void erase(const Variant& p_key);
void erase(const Variant &p_key);
bool operator==(const Dictionary& p_dictionary) const;
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(const Dictionary& p_from);
Dictionary(bool p_shared=false);
Dictionary(const Dictionary &p_from);
Dictionary(bool p_shared = false);
~Dictionary();
};

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -28,5 +29,4 @@
/*************************************************************************/
#include "dvector.h"
Mutex* dvector_lock=NULL;
Mutex *dvector_lock = NULL;

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,20 +32,17 @@
#include "os/memory.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
extern Mutex *dvector_lock;
extern Mutex* dvector_lock;
template<class T>
template <class T>
class DVector {
mutable MID mem;
void copy_on_write() {
if (!mem.is_valid())
@@ -53,56 +51,54 @@ class DVector {
if (dvector_lock)
dvector_lock->lock();
MID_Lock lock( mem );
MID_Lock lock(mem);
if ( *(int*)lock.data() == 1 ) {
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() );
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
ERR_FAIL_COND(new_mem.is_valid()); // out of memory
}
MID_Lock dst_lock( new_mem );
MID_Lock dst_lock(new_mem);
int *rc = (int*)dst_lock.data();
int *rc = (int *)dst_lock.data();
*rc=1;
*rc = 1;
T * dst = (T*)(rc + 1 );
T *dst = (T *)(rc + 1);
T * src =(T*) ((int*)lock.data() + 1 );
T *src = (T *)((int *)lock.data() + 1);
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
for (int i=0;i<count;i++) {
for (int i = 0; i < count; i++) {
memnew_placement( &dst[i], T(src[i]) );
memnew_placement(&dst[i], T(src[i]));
}
(*(int*)lock.data())--;
(*(int *)lock.data())--;
// unlock all
dst_lock=MID_Lock();
lock=MID_Lock();
dst_lock = MID_Lock();
lock = MID_Lock();
mem=new_mem;
mem = new_mem;
if (dvector_lock)
dvector_lock->unlock();
}
void reference( const DVector& p_dvector ) {
void reference(const DVector &p_dvector) {
unreference();
@@ -118,18 +114,16 @@ class DVector {
MID_Lock lock(p_dvector.mem);
int * rc = (int*)lock.data();
int *rc = (int *)lock.data();
(*rc)++;
lock = MID_Lock();
mem=p_dvector.mem;
mem = p_dvector.mem;
if (dvector_lock)
dvector_lock->unlock();
}
void unreference() {
if (dvector_lock)
@@ -144,65 +138,60 @@ class DVector {
MID_Lock lock(mem);
int * rc = (int*)lock.data();
int *rc = (int *)lock.data();
(*rc)--;
if (*rc==0) {
if (*rc == 0) {
// no one else using it, destruct
T * t= (T*)(rc+1);
T *t = (T *)(rc + 1);
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
for (int i=0;i<count;i++) {
for (int i = 0; i < count; i++) {
t[i].~T();
}
}
lock = MID_Lock();
mem = MID ();
mem = MID();
if (dvector_lock)
dvector_lock->unlock();
}
public:
class Read {
friend class DVector;
friend class DVector;
MID_Lock lock;
const T * mem;
public:
const T *mem;
_FORCE_INLINE_ const T& operator[](int p_index) const { return mem[p_index]; }
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; }
Read() { mem = NULL; }
};
class Write {
friend class DVector;
friend class DVector;
MID_Lock lock;
T * mem;
public:
T *mem;
_FORCE_INLINE_ T& operator[](int p_index) { return mem[p_index]; }
public:
_FORCE_INLINE_ T &operator[](int p_index) { return mem[p_index]; }
_FORCE_INLINE_ T *ptr() { return mem; }
Write() { mem=NULL; }
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);
r.lock = MID_Lock(mem);
r.mem = (const T *)((int *)r.lock.data() + 1);
}
return r;
}
@@ -211,74 +200,70 @@ public:
Write w;
if (mem.is_valid()) {
copy_on_write();
w.lock = MID_Lock( mem );
w.mem = (T*)((int*)w.lock.data()+1);
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) {
template <class MC>
void fill_with(const MC &p_mc) {
int c=p_mc.size();
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()) {
Write w = write();
int idx = 0;
for (const typename MC::Element *E = p_mc.front(); E; E = E->next()) {
w[idx++]=E->get();
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++) {
for (int i = p_index; i < s - 1; i++) {
w[i]=w[i+1];
w[i] = w[i + 1];
};
w = Write();
resize(s-1);
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) {
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)
if (ds == 0)
return;
int bs = size();
resize( bs + ds);
resize(bs + ds);
Write w = write();
Read r = p_arr.read();
for(int i=0;i<ds;i++)
w[bs+i]=r[i];
for (int i = 0; i < ds; i++)
w[bs + i] = r[i];
}
Error insert(int p_pos, const T &p_val) {
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);
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;
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;
@@ -287,49 +272,48 @@ public:
void invert();
void operator=(const DVector& p_dvector) { reference(p_dvector); }
void operator=(const DVector &p_dvector) { reference(p_dvector); }
DVector() {}
DVector(const DVector& p_dvector) { reference(p_dvector); }
DVector(const DVector &p_dvector) { reference(p_dvector); }
~DVector() { unreference(); }
};
template<class T>
template <class T>
int DVector<T>::size() const {
return mem.is_valid() ? ((mem.get_size() - sizeof(int)) / sizeof(T) ) : 0;
return mem.is_valid() ? ((mem.get_size() - sizeof(int)) / sizeof(T)) : 0;
}
template<class T>
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) {
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());
if (p_index < 0 || p_index >= size()) {
ERR_FAIL_COND(p_index < 0 || p_index >= size());
}
Write w = write();
w[p_index]=p_val;
w[p_index] = p_val;
}
template<class T>
void DVector<T>::push_back(const T& p_val) {
template <class T>
void DVector<T>::push_back(const T &p_val) {
resize( size() + 1 );
set( size() -1, p_val );
resize(size() + 1);
set(size() - 1, p_val);
}
template<class T>
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);
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();
@@ -337,14 +321,13 @@ const T DVector<T>::operator[](int p_index) const {
return r[p_index];
}
template<class T>
template <class T>
Error DVector<T>::resize(int p_size) {
if (dvector_lock)
dvector_lock->lock();
bool same = p_size==size();
bool same = p_size == size();
if (dvector_lock)
dvector_lock->unlock();
@@ -353,89 +336,82 @@ Error DVector<T>::resize(int p_size) {
if (same)
return OK;
if (p_size == 0 ) {
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.
ERR_FAIL_COND_V(mem.is_locked(), ERR_LOCKED); // if after copy on write, memory is locked, fail.
if (p_size > size() ) {
if (p_size > size()) {
int oldsize=size();
int oldsize = size();
MID_Lock lock;
if (oldsize==0) {
if (oldsize == 0) {
mem = dynalloc( p_size * sizeof(T) + sizeof(int) );
lock=MID_Lock(mem);
int *rc = ((int*)lock.data());
*rc=1;
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 ) {
if (dynrealloc(mem, p_size * sizeof(T) + sizeof(int)) != OK) {
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // out of memory
}
lock=MID_Lock(mem);
lock = MID_Lock(mem);
}
T *t = (T *)((int *)lock.data() + 1);
for (int i = oldsize; i < p_size; i++) {
T *t = (T*)((int*)lock.data() + 1);
for (int i=oldsize;i<p_size;i++) {
memnew_placement(&t[i], T );
memnew_placement(&t[i], T);
}
lock = MID_Lock(); // clear
} else {
int oldsize=size();
int oldsize = size();
MID_Lock lock(mem);
T *t = (T *)((int *)lock.data() + 1);
T *t = (T*)((int*)lock.data() + 1);
for (int i=p_size;i<oldsize;i++) {
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 ) {
if (dynrealloc(mem, p_size * sizeof(T) + sizeof(int)) != OK) {
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error
}
}
return OK;
}
template<class T>
template <class T>
void DVector<T>::invert() {
T temp;
Write w = write();
int s = size();
int half_s = s/2;
int half_s = s / 2;
for(int i=0;i<half_s;i++) {
for (int i = 0; i < half_s; i++) {
temp = w[i];
w[i] = w[s-i-1];
w[s-i-1] = temp;
w[i] = w[s - i - 1];
w[s - i - 1] = temp;
}
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -47,7 +48,7 @@ enum Error {
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,
@@ -57,40 +58,37 @@ enum Error {
ERR_FILE_MISSING_DEPENDENCIES,
ERR_FILE_EOF,
ERR_CANT_OPEN, ///< Can't open a resource/socket/file
ERR_CANT_CREATE,
ERROR_QUERY_FAILED, // (20)
ERR_CANT_CREATE, // (20)
ERROR_QUERY_FAILED,
ERR_ALREADY_IN_USE,
ERR_LOCKED, ///< resource is locked
ERR_TIMEOUT,
ERR_CANT_CONNECT,
ERR_CANT_RESOLVE, // (25)
ERR_LOCKED, ///< resource is locked
ERR_TIMEOUT,
ERR_CANT_CONNECT, // (25)
ERR_CANT_RESOLVE,
ERR_CONNECTION_ERROR,
ERR_CANT_AQUIRE_RESOURCE,
ERR_CANT_AQUIRE_RESOURCE,
ERR_CANT_FORK,
ERR_INVALID_DATA, ///< Data passed is invalid
ERR_INVALID_PARAMETER, ///< Parameter passed is invalid (30)
ERR_INVALID_DATA, ///< Data passed is invalid (30)
ERR_INVALID_PARAMETER, ///< Parameter passed is invalid
ERR_ALREADY_EXISTS, ///< When adding, item already exists
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
ERR_COMPILATION_FAILED, // (35)
ERR_METHOD_NOT_FOUND,
ERR_LINK_FAILED,
ERR_DATABASE_CANT_WRITE, ///< database is full (35)
ERR_COMPILATION_FAILED,
ERR_METHOD_NOT_FOUND,
ERR_LINK_FAILED,
ERR_SCRIPT_FAILED,
ERR_CYCLIC_LINK,
ERR_INVALID_DECLARATION, // (40)
ERR_CYCLIC_LINK, // (40)
ERR_INVALID_DECLARATION,
ERR_DUPLICATE_SYMBOL,
ERR_PARSE_ERROR,
ERR_BUSY,
ERR_SKIP,
ERR_HELP, ///< user requested help!! (45)
ERR_SKIP, // (45)
ERR_HELP, ///< user requested help!!
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

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,12 +30,11 @@
#include "error_macros.h"
#include "os/os.h"
bool _err_error_exists = false;
bool _err_error_exists=false;
static ErrorHandlerList *error_handler_list = NULL;
static ErrorHandlerList *error_handler_list=NULL;
void _err_set_last_error(const char* p_err) {
void _err_set_last_error(const char *p_err) {
OS::get_singleton()->set_last_error(p_err);
}
@@ -47,8 +47,8 @@ void _err_clear_last_error() {
void add_error_handler(ErrorHandlerList *p_handler) {
_global_lock();
p_handler->next=error_handler_list;
error_handler_list=p_handler;
p_handler->next = error_handler_list;
error_handler_list = p_handler;
_global_unlock();
}
@@ -59,44 +59,39 @@ void remove_error_handler(ErrorHandlerList *p_handler) {
ErrorHandlerList *prev = NULL;
ErrorHandlerList *l = error_handler_list;
while(l) {
while (l) {
if (l==p_handler) {
if (l == p_handler) {
if (prev)
prev->next=l->next;
prev->next = l->next;
else
error_handler_list=l->next;
error_handler_list = l->next;
break;
}
prev=l;
l=l->next;
prev = l;
l = l->next;
}
_global_unlock();
}
void _err_print_error(const char* p_function, const char* p_file,int p_line,const char *p_error,ErrorHandlerType p_type) {
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type) {
OS::get_singleton()->print_error(p_function,p_file,p_line,p_error,_err_error_exists?OS::get_singleton()->get_last_error():"",(OS::ErrorType)p_type);
OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, _err_error_exists ? OS::get_singleton()->get_last_error() : "", (OS::ErrorType)p_type);
_global_lock();
ErrorHandlerList *l = error_handler_list;
while(l) {
while (l) {
l->errfunc(l->userdata,p_function,p_file,p_line,p_error,_err_error_exists?OS::get_singleton()->get_last_error():"",p_type);
l=l->next;
l->errfunc(l->userdata, p_function, p_file, p_line, p_error, _err_error_exists ? OS::get_singleton()->get_last_error() : "", p_type);
l = l->next;
}
_global_unlock();
if (_err_error_exists) {
OS::get_singleton()->clear_last_error();
_err_error_exists=false;
_err_error_exists = false;
}
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,7 +30,6 @@
#ifndef ERROR_MACROS_H
#define ERROR_MACROS_H
/**
* Error macros. Unlike exceptions and asserts, these macros try to mantain consistency and stability
* inside the code. It is recommended to always return processable data, so in case of an error, the
@@ -52,8 +52,8 @@ enum ErrorHandlerType {
ERR_HANDLER_SCRIPT
};
typedef void (*ErrorHandlerFunc)(void*,const char*,const char*,int p_line,const char *, const char *,ErrorHandlerType p_type);
void _err_set_last_error(const char* p_err);
typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
void _err_set_last_error(const char *p_err);
void _err_clear_last_error();
struct ErrorHandlerList {
@@ -61,22 +61,26 @@ struct ErrorHandlerList {
ErrorHandlerFunc errfunc;
void *userdata;
ErrorHandlerList*next;
ErrorHandlerList *next;
ErrorHandlerList() { errfunc=0; next=0; userdata=0; }
ErrorHandlerList() {
errfunc = 0;
next = 0;
userdata = 0;
}
};
void add_error_handler(ErrorHandlerList *p_handler);
void remove_error_handler(ErrorHandlerList *p_handler);
void _err_print_error(const char* p_function,const char* p_file,int p_line,const char *p_error,ErrorHandlerType p_type=ERR_HANDLER_ERROR);
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
#ifndef _STR
#define _STR(m_x) #m_x
#define _MKSTR(m_x) _STR(m_x)
#endif
#define _FNL __FILE__":"
#define _FNL __FILE__ ":"
/** An index has failed if m_index<0 or m_index >=m_size, the function exists */
@@ -85,13 +89,21 @@ extern bool _err_error_exists;
#ifdef DEBUG_ENABLED
/** Print a warning string.
*/
#define ERR_EXPLAINC(m_reason) {_err_set_last_error(m_reason); _err_error_exists=true;}
#define ERR_EXPLAIN(m_string) {_err_set_last_error(String(m_string).utf8().get_data()); _err_error_exists=true;}
#define ERR_EXPLAINC(m_reason) \
{ \
_err_set_last_error(m_reason); \
_err_error_exists = true; \
}
#define ERR_EXPLAIN(m_string) \
{ \
_err_set_last_error(String(m_string).utf8().get_data()); \
_err_error_exists = true; \
}
#else
#define ERR_EXPLAIN( m_text )
#define ERR_EXPLAINC( m_text )
#define ERR_EXPLAIN(m_text)
#define ERR_EXPLAINC(m_text)
#endif
@@ -102,49 +114,63 @@ extern bool _err_error_exists;
#define FUNCTION_STR __FUNCTION__
#endif
#define ERR_FAIL_INDEX(m_index,m_size) \
do {if ((m_index)<0 || (m_index)>=(m_size)) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index " _STR(m_index)" out of size (" _STR(m_size)")."); \
return; \
} else _err_error_exists=false; } while(0); \
#define ERR_FAIL_INDEX(m_index, m_size) \
do { \
if ((m_index) < 0 || (m_index) >= (m_size)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Index " _STR(m_index) " out of size (" _STR(m_size) ")."); \
return; \
} else \
_err_error_exists = false; \
} while (0);
/** An index has failed if m_index<0 or m_index >=m_size, the function exists.
* This function returns an error value, if returning Error, please select the most
* appropriate error condition from error_macros.h
*/
#define ERR_FAIL_INDEX_V(m_index,m_size,m_retval) \
do {if ((m_index)<0 || (m_index)>=(m_size)) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index " _STR(m_index)" out of size (" _STR(m_size)")."); \
return m_retval; \
} else _err_error_exists=false;} while (0);
#define ERR_FAIL_INDEX_V(m_index, m_size, m_retval) \
do { \
if ((m_index) < 0 || (m_index) >= (m_size)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Index " _STR(m_index) " out of size (" _STR(m_size) ")."); \
return m_retval; \
} else \
_err_error_exists = false; \
} while (0);
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
*/
#define ERR_FAIL_NULL(m_param) \
{ if ( !m_param ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' " _STR(m_param)" ' is null."); \
return; \
}else _err_error_exists=false; } \
#define ERR_FAIL_NULL(m_param) \
{ \
if (!m_param) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \
return; \
} else \
_err_error_exists = false; \
}
#define ERR_FAIL_NULL_V(m_param,m_retval) \
{ if ( !m_param ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' " _STR(m_param)" ' is null."); \
return m_retval; \
}else _err_error_exists=false; } \
#define ERR_FAIL_NULL_V(m_param, m_retval) \
{ \
if (!m_param) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \
return m_retval; \
} else \
_err_error_exists = false; \
}
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
*/
#define ERR_FAIL_COND(m_cond) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true."); \
return; \
}else _err_error_exists=false; } \
#define ERR_FAIL_COND(m_cond) \
{ \
if (m_cond) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true."); \
return; \
} else \
_err_error_exists = false; \
}
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
@@ -152,81 +178,89 @@ extern bool _err_error_exists;
* appropriate error condition from error_macros.h
*/
#define ERR_FAIL_COND_V(m_cond,m_retval) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. returned: " _STR(m_retval)); \
return m_retval; \
}else _err_error_exists=false; } \
#define ERR_FAIL_COND_V(m_cond, m_retval) \
{ \
if (m_cond) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. returned: " _STR(m_retval)); \
return m_retval; \
} else \
_err_error_exists = false; \
}
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will skip to the next iteration.
*/
#define ERR_CONTINUE(m_cond) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. Continuing..:"); \
continue;\
} else _err_error_exists=false;} \
#define ERR_CONTINUE(m_cond) \
{ \
if (m_cond) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Continuing..:"); \
continue; \
} else \
_err_error_exists = false; \
}
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will break
*/
#define ERR_BREAK(m_cond) \
{ if ( m_cond ) { \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. Breaking..:"); \
break;\
} else _err_error_exists=false;} \
#define ERR_BREAK(m_cond) \
{ \
if (m_cond) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Breaking..:"); \
break; \
} else \
_err_error_exists = false; \
}
/** Print an error string and return
*/
#define ERR_FAIL() \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Method/Function Failed."); \
_err_error_exists=false;\
return;\
} \
#define ERR_FAIL() \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed."); \
_err_error_exists = false; \
return; \
}
/** Print an error string and return with value
*/
#define ERR_FAIL_V(m_value) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Method/Function Failed, returning: " __STR(m_value)); \
_err_error_exists=false; \
return m_value;\
} \
#define ERR_FAIL_V(m_value) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_value)); \
_err_error_exists = false; \
return m_value; \
}
/** Print an error string.
*/
#define ERR_PRINT(m_string) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,m_string); \
_err_error_exists=false;\
} \
#define ERR_PRINT(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
_err_error_exists = false; \
}
#define ERR_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,String(m_string).utf8().get_data()); \
_err_error_exists=false;\
} \
#define ERR_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, String(m_string).utf8().get_data()); \
_err_error_exists = false; \
}
/** Print a warning string.
*/
#define WARN_PRINT(m_string) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,m_string,ERR_HANDLER_WARNING); \
_err_error_exists=false;\
} \
#define WARN_PRINT(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
_err_error_exists = false; \
}
#define WARN_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,String(m_string).utf8().get_data(),ERR_HANDLER_WARNING); \
_err_error_exists=false;\
} \
#define WARN_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, String(m_string).utf8().get_data(), ERR_HANDLER_WARNING); \
_err_error_exists = false; \
}
#endif

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -28,134 +29,129 @@
/*************************************************************************/
#include "event_queue.h"
Error EventQueue::push_call(uint32_t p_instance_ID, const StringName &p_method, VARIANT_ARG_DECLARE) {
Error EventQueue::push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_DECLARE) {
uint8_t room_needed=sizeof(Event);
int args=0;
if (p_arg5.get_type()!=Variant::NIL)
args=5;
else if (p_arg4.get_type()!=Variant::NIL)
args=4;
else if (p_arg3.get_type()!=Variant::NIL)
args=3;
else if (p_arg2.get_type()!=Variant::NIL)
args=2;
else if (p_arg1.get_type()!=Variant::NIL)
args=1;
uint8_t room_needed = sizeof(Event);
int args = 0;
if (p_arg5.get_type() != Variant::NIL)
args = 5;
else if (p_arg4.get_type() != Variant::NIL)
args = 4;
else if (p_arg3.get_type() != Variant::NIL)
args = 3;
else if (p_arg2.get_type() != Variant::NIL)
args = 2;
else if (p_arg1.get_type() != Variant::NIL)
args = 1;
else
args=0;
args = 0;
room_needed+=sizeof(Variant)*args;
room_needed += sizeof(Variant) * args;
ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY );
Event * ev = memnew_placement( &event_buffer[ buffer_end ], Event );
ev->args=args;
ev->instance_ID=p_instance_ID;
ev->method=p_method;
ERR_FAIL_COND_V((buffer_end + room_needed) >= buffer_size, ERR_OUT_OF_MEMORY);
Event *ev = memnew_placement(&event_buffer[buffer_end], Event);
ev->args = args;
ev->instance_ID = p_instance_ID;
ev->method = p_method;
buffer_end+=sizeof(Event);
buffer_end += sizeof(Event);
if (args>=1) {
if (args >= 1) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg1;
Variant *v = memnew_placement(&event_buffer[buffer_end], Variant);
buffer_end += sizeof(Variant);
*v = p_arg1;
}
if (args>=2) {
if (args >= 2) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg2;
Variant *v = memnew_placement(&event_buffer[buffer_end], Variant);
buffer_end += sizeof(Variant);
*v = p_arg2;
}
if (args>=3) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg3;
if (args >= 3) {
Variant *v = memnew_placement(&event_buffer[buffer_end], Variant);
buffer_end += sizeof(Variant);
*v = p_arg3;
}
if (args>=4) {
if (args >= 4) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg4;
Variant *v = memnew_placement(&event_buffer[buffer_end], Variant);
buffer_end += sizeof(Variant);
*v = p_arg4;
}
if (args>=5) {
if (args >= 5) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant);
*v=p_arg5;
Variant *v = memnew_placement(&event_buffer[buffer_end], Variant);
buffer_end += sizeof(Variant);
*v = p_arg5;
}
if (buffer_end > buffer_max_used)
buffer_max_used=buffer_end;
buffer_max_used = buffer_end;
return OK;
}
void EventQueue::flush_events() {
uint32_t read_pos=0;
uint32_t read_pos = 0;
while (read_pos < buffer_end ) {
while (read_pos < buffer_end) {
Event *event = (Event*)&event_buffer[ read_pos ];
Variant *args= (Variant*)(event+1);
Event *event = (Event *)&event_buffer[read_pos];
Variant *args = (Variant *)(event + 1);
Object *obj = ObjectDB::get_instance(event->instance_ID);
if (obj) {
// events don't expect a return value
obj->call( event->method,
(event->args>=1) ? args[0] : Variant(),
(event->args>=2) ? args[1] : Variant(),
(event->args>=3) ? args[2] : Variant(),
(event->args>=4) ? args[3] : Variant(),
(event->args>=5) ? args[4] : Variant() );
obj->call(event->method,
(event->args >= 1) ? args[0] : Variant(),
(event->args >= 2) ? args[1] : Variant(),
(event->args >= 3) ? args[2] : Variant(),
(event->args >= 4) ? args[3] : Variant(),
(event->args >= 5) ? args[4] : Variant());
}
if (event->args>=1) args[0].~Variant();
if (event->args>=2) args[1].~Variant();
if (event->args>=3) args[2].~Variant();
if (event->args>=4) args[3].~Variant();
if (event->args>=5) args[4].~Variant();
if (event->args >= 1) args[0].~Variant();
if (event->args >= 2) args[1].~Variant();
if (event->args >= 3) args[2].~Variant();
if (event->args >= 4) args[3].~Variant();
if (event->args >= 5) args[4].~Variant();
event->~Event();
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
read_pos += sizeof(Event) + sizeof(Variant) * event->args;
}
buffer_end=0; // reset buffer
buffer_end = 0; // reset buffer
}
EventQueue::EventQueue(uint32_t p_buffer_size) {
buffer_end=0;
buffer_max_used=0;
buffer_size=p_buffer_size;
event_buffer = memnew_arr( uint8_t, buffer_size );
buffer_end = 0;
buffer_max_used = 0;
buffer_size = p_buffer_size;
event_buffer = memnew_arr(uint8_t, buffer_size);
}
EventQueue::~EventQueue() {
uint32_t read_pos=0;
uint32_t read_pos = 0;
while (read_pos < buffer_end ) {
while (read_pos < buffer_end) {
Event *event = (Event*)&event_buffer[ read_pos ];
Variant *args= (Variant*)(event+1);
for (int i=0;i<event->args;i++)
Event *event = (Event *)&event_buffer[read_pos];
Variant *args = (Variant *)(event + 1);
for (int i = 0; i < event->args; i++)
args[i].~Variant();
event->~Event();
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
read_pos += sizeof(Event) + sizeof(Variant) * event->args;
}
memdelete_arr(event_buffer);
event_buffer=NULL;
event_buffer = NULL;
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -37,7 +38,7 @@ class EventQueue {
enum {
DEFAULT_EVENT_QUEUE_SIZE_KB=256
DEFAULT_EVENT_QUEUE_SIZE_KB = 256
};
struct Event {
@@ -47,20 +48,17 @@ class EventQueue {
int args;
};
uint8_t *event_buffer;
uint32_t buffer_end;
uint32_t buffer_max_used;
uint32_t buffer_size;
public:
Error push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_LIST);
Error push_call(uint32_t p_instance_ID, const StringName &p_method, VARIANT_ARG_LIST);
void flush_events();
EventQueue(uint32_t p_buffer_size=DEFAULT_EVENT_QUEUE_SIZE_KB*1024);
EventQueue(uint32_t p_buffer_size = DEFAULT_EVENT_QUEUE_SIZE_KB * 1024);
~EventQueue();
};
#endif

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -28,55 +29,50 @@
/*************************************************************************/
#include "func_ref.h"
Variant FuncRef::call_func(const Variant** p_args, int p_argcount, Variant::CallError& r_error) {
Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
if (id==0) {
r_error.error=Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
if (id == 0) {
r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
Object* obj = ObjectDB::get_instance(id);
Object *obj = ObjectDB::get_instance(id);
if (!obj) {
r_error.error=Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
return obj->call(function,p_args,p_argcount,r_error);
return obj->call(function, p_args, p_argcount, r_error);
}
void FuncRef::set_instance(Object *p_obj){
void FuncRef::set_instance(Object *p_obj) {
ERR_FAIL_NULL(p_obj);
id=p_obj->get_instance_ID();
id = p_obj->get_instance_ID();
}
void FuncRef::set_function(const StringName& p_func){
void FuncRef::set_function(const StringName &p_func) {
function=p_func;
function = p_func;
}
void FuncRef::_bind_methods() {
{
MethodInfo mi;
mi.name="call_func";
mi.name = "call_func";
Vector<Variant> defargs;
for(int i=0;i<10;i++) {
mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i)));
for (int i = 0; i < 10; i++) {
mi.arguments.push_back(PropertyInfo(Variant::NIL, "arg" + itos(i)));
defargs.push_back(Variant());
}
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call_func:Variant",&FuncRef::call_func,mi,defargs);
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT, "call_func", &FuncRef::call_func, mi, defargs);
}
ObjectTypeDB::bind_method(_MD("set_instance","instance"),&FuncRef::set_instance);
ObjectTypeDB::bind_method(_MD("set_function","name"),&FuncRef::set_function);
ObjectTypeDB::bind_method(_MD("set_instance", "instance"), &FuncRef::set_instance);
ObjectTypeDB::bind_method(_MD("set_function", "name"), &FuncRef::set_function);
}
FuncRef::FuncRef() {
FuncRef::FuncRef(){
id=0;
id = 0;
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,20 +32,19 @@
#include "reference.h"
class FuncRef : public Reference{
class FuncRef : public Reference {
OBJ_TYPE(FuncRef,Reference);
OBJ_TYPE(FuncRef, Reference);
ObjectID id;
StringName function;
protected:
static void _bind_methods();
public:
Variant call_func(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
public:
Variant call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
void set_instance(Object *p_obj);
void set_function(const StringName& p_func);
void set_function(const StringName &p_func);
FuncRef();
};

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,10 +30,8 @@
#ifndef GLOBAL_CONSTANTS_H
#define GLOBAL_CONSTANTS_H
class GlobalConstants {
public:
static int get_global_constant_count();
static const char *get_global_constant_name(int p_idx);
static int get_global_constant_value(int p_idx);

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -30,32 +31,32 @@
#define GLOBALS_H
#include "object.h"
#include "set.h"
#include "os/thread_safe.h"
#include "set.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
class Globals : public Object {
OBJ_TYPE( Globals, Object );
OBJ_TYPE(Globals, Object);
_THREAD_SAFE_CLASS_
public:
typedef Map<String,Variant> CustomMap;
typedef Map<String, Variant> CustomMap;
struct Singleton {
StringName name;
Object *ptr;
Singleton(const StringName& p_name=StringName(), Object *p_ptr=NULL) { name=p_name; ptr=p_ptr; }
Singleton(const StringName &p_name = StringName(), Object *p_ptr = NULL) {
name = p_name;
ptr = p_ptr;
}
};
protected:
enum {
NO_ORDER_BASE=1<<18
NO_ORDER_BASE = 1 << 18
};
struct VariantContainer {
@@ -64,22 +65,32 @@ protected:
Variant variant;
bool hide_from_editor;
bool overrided;
VariantContainer(){ order=0; hide_from_editor=false; persist=false; overrided=false; }
VariantContainer(const Variant& p_variant, int p_order, bool p_persist=false) { variant=p_variant; order=p_order; hide_from_editor=false; persist=p_persist; overrided=false; }
VariantContainer() {
order = 0;
hide_from_editor = false;
persist = false;
overrided = false;
}
VariantContainer(const Variant &p_variant, int p_order, bool p_persist = false) {
variant = p_variant;
order = p_order;
hide_from_editor = false;
persist = p_persist;
overrided = false;
}
};
bool registering_order;
int last_order;
Map<StringName,VariantContainer> props;
Map<StringName, VariantContainer> props;
String resource_path;
Map<StringName,PropertyInfo> custom_prop_info;
Map<StringName, PropertyInfo> custom_prop_info;
bool disable_platform_override;
bool using_datapack;
List<String> input_presets;
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) 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 Globals *singleton;
@@ -87,53 +98,53 @@ protected:
Error _load_settings(const String p_path);
Error _load_settings_binary(const String p_path);
Error _save_settings_text(const String& p_file,const Map<String,List<String> > &props,const CustomMap& p_custom=CustomMap());
Error _save_settings_binary(const String& p_file,const Map<String,List<String> > &props,const CustomMap& p_custom=CustomMap());
Error _save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap());
Error _save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap());
List<Singleton> singletons;
Error _save_custom_bnd(const String& p_file);
Error _save_custom_bnd(const String &p_file);
bool _load_resource_pack(const String& p_pack);
bool _load_resource_pack(const String &p_pack);
void _add_property_info_bind(const Dictionary &p_info);
protected:
static void _bind_methods();
public:
bool has(String p_var) const;
String localize_path(const String& p_path) const;
String globalize_path(const String& p_path) const;
String localize_path(const String &p_path) const;
String globalize_path(const String &p_path) const;
void set_persisting(const String& p_name, bool p_persist);
bool is_persisting(const String& p_name) const;
void set_persisting(const String &p_name, bool p_persist);
bool is_persisting(const String &p_name) const;
String get_resource_path() const;
static Globals *get_singleton();
void clear(const String& p_name);
int get_order(const String& p_name) const;
void set_order(const String& p_name, int p_order);
void clear(const String &p_name);
int get_order(const String &p_name) const;
void set_order(const String &p_name, int p_order);
Error setup(const String& p_path, const String &p_main_pack);
Error setup(const String &p_path, const String &p_main_pack);
Error save_custom(const String& p_path="",const CustomMap& p_custom=CustomMap(),const Set<String>& p_ignore_masks=Set<String>());
Error save_custom(const String &p_path = "", const CustomMap &p_custom = CustomMap(), const Set<String> &p_ignore_masks = Set<String>());
Error save();
void set_custom_property_info(const String& p_prop,const PropertyInfo& p_info);
void set_custom_property_info(const String &p_prop, const PropertyInfo &p_info);
void add_singleton(const Singleton &p_singleton);
void get_singletons(List<Singleton> *p_singletons);
bool has_singleton(const String& p_name) const;
bool has_singleton(const String &p_name) const;
Vector<String> get_optimizer_presets() const;
List<String> get_input_presets() const { return input_presets; }
void set_disable_platform_override(bool p_disable);
Object* get_singleton_object(const String& p_name) const;
Object *get_singleton_object(const String &p_name) const;
void register_global_defaults();
@@ -143,10 +154,9 @@ public:
Globals();
~Globals();
};
//not a macro any longer
Variant _GLOBAL_DEF( const String& p_var, const Variant& p_default);
#define GLOBAL_DEF(m_var,m_value) _GLOBAL_DEF(m_var,m_value)
Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default);
#define GLOBAL_DEF(m_var, m_value) _GLOBAL_DEF(m_var, m_value)
#endif

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,39 +30,36 @@
#ifndef HASH_MAP_H
#define HASH_MAP_H
#include "hashfuncs.h"
#include "error_macros.h"
#include "ustring.h"
#include "os/memory.h"
#include "hashfuncs.h"
#include "list.h"
#include "os/memory.h"
#include "ustring.h"
class HashMapHahserDefault {
public:
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) {
uint64_t v=p_int;
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) {
uint64_t v = p_int;
v = (~v) + (v << 18); // v = (v << 18) - v - 1;
v = v ^ (v >> 31);
v = v * 21; // v = (v + (v << 2)) + (v << 4);
v = v ^ (v >> 11);
v = v + (v << 6);
v = v ^ (v >> 22);
return (int) v;
return (int)v;
}
static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash(uint64_t(p_int)); }
static _FORCE_INLINE_ uint32_t hash(const int64_t p_int) { return hash(uint64_t(p_int)); }
static _FORCE_INLINE_ uint32_t hash(const uint32_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int32_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const uint16_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int16_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; }
// static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); }
static _FORCE_INLINE_ uint32_t hash(const uint32_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int32_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const uint16_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int16_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; }
// static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); }
};
/**
@@ -80,20 +78,21 @@ public:
*
*/
template<class TKey, class TData, class Hasher=HashMapHahserDefault,uint8_t MIN_HASH_TABLE_POWER=3,uint8_t RELATIONSHIP=8>
template <class TKey, class TData, class Hasher = HashMapHahserDefault, uint8_t MIN_HASH_TABLE_POWER = 3, uint8_t RELATIONSHIP = 8>
class HashMap {
public:
struct Pair {
TKey key;
TData data;
Pair() {}
Pair(const TKey& p_key, const TData& p_data) { key=p_key; data=p_data; }
Pair(const TKey &p_key, const TData &p_data) {
key = p_key;
data = p_data;
}
};
private:
struct Entry {
@@ -101,7 +100,7 @@ private:
Entry *next;
Pair pair;
Entry() { next=0; }
Entry() { next = 0; }
};
Entry **hash_table;
@@ -110,206 +109,192 @@ private:
void make_hash_table() {
ERR_FAIL_COND( hash_table );
ERR_FAIL_COND(hash_table);
hash_table = memnew_arr( Entry*, (1<<MIN_HASH_TABLE_POWER) );
hash_table = memnew_arr(Entry *, (1 << MIN_HASH_TABLE_POWER));
hash_table_power = MIN_HASH_TABLE_POWER;
elements=0;
for (int i=0;i<(1<<MIN_HASH_TABLE_POWER);i++)
hash_table[i]=0;
elements = 0;
for (int i = 0; i < (1 << MIN_HASH_TABLE_POWER); i++)
hash_table[i] = 0;
}
void erase_hash_table() {
ERR_FAIL_COND(elements);
memdelete_arr( hash_table );
hash_table=0;
hash_table_power=0;
elements=0;
memdelete_arr(hash_table);
hash_table = 0;
hash_table_power = 0;
elements = 0;
}
void check_hash_table() {
int new_hash_table_power=-1;
int new_hash_table_power = -1;
if ((int)elements > ( (1<<hash_table_power) * RELATIONSHIP ) ) {
if ((int)elements > ((1 << hash_table_power) * RELATIONSHIP)) {
/* rehash up */
new_hash_table_power=hash_table_power+1;
new_hash_table_power = hash_table_power + 1;
while( (int)elements > ( (1<<new_hash_table_power) * RELATIONSHIP ) ) {
while ((int)elements > ((1 << new_hash_table_power) * RELATIONSHIP)) {
new_hash_table_power++;
}
} else if ( (hash_table_power>(int)MIN_HASH_TABLE_POWER) && ((int)elements < ( (1<<(hash_table_power-1)) * RELATIONSHIP ) ) ) {
} else if ((hash_table_power > (int)MIN_HASH_TABLE_POWER) && ((int)elements < ((1 << (hash_table_power - 1)) * RELATIONSHIP))) {
/* rehash down */
new_hash_table_power=hash_table_power-1;
new_hash_table_power = hash_table_power - 1;
while( (int)elements < ( (1<<(new_hash_table_power-1)) * RELATIONSHIP ) ) {
while ((int)elements < ((1 << (new_hash_table_power - 1)) * RELATIONSHIP)) {
new_hash_table_power--;
}
if (new_hash_table_power<(int)MIN_HASH_TABLE_POWER)
new_hash_table_power=MIN_HASH_TABLE_POWER;
if (new_hash_table_power < (int)MIN_HASH_TABLE_POWER)
new_hash_table_power = MIN_HASH_TABLE_POWER;
}
if (new_hash_table_power==-1)
if (new_hash_table_power == -1)
return;
Entry ** new_hash_table = memnew_arr( Entry*, (1<<new_hash_table_power) );
Entry **new_hash_table = memnew_arr(Entry *, (1 << new_hash_table_power));
if (!new_hash_table) {
ERR_PRINT("Out of Memory");
return;
}
for (int i=0;i<(1<<new_hash_table_power);i++) {
for (int i = 0; i < (1 << new_hash_table_power); i++) {
new_hash_table[i]=0;
new_hash_table[i] = 0;
}
for (int i=0;i<(1<<hash_table_power);i++) {
for (int i = 0; i < (1 << hash_table_power); i++) {
while( hash_table[i] ) {
while (hash_table[i]) {
Entry *se=hash_table[i];
hash_table[i]=se->next;
int new_pos = se->hash & ((1<<new_hash_table_power)-1);
se->next=new_hash_table[new_pos];
new_hash_table[new_pos]=se;
Entry *se = hash_table[i];
hash_table[i] = se->next;
int new_pos = se->hash & ((1 << new_hash_table_power) - 1);
se->next = new_hash_table[new_pos];
new_hash_table[new_pos] = se;
}
}
if (hash_table)
memdelete_arr( hash_table );
hash_table=new_hash_table;
hash_table_power=new_hash_table_power;
memdelete_arr(hash_table);
hash_table = new_hash_table;
hash_table_power = new_hash_table_power;
}
/* I want to have only one function.. */
_FORCE_INLINE_ const Entry * get_entry( const TKey& p_key ) const {
_FORCE_INLINE_ const Entry *get_entry(const TKey &p_key) const {
uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1);
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
Entry *e = hash_table[index];
while (e) {
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_key ) {
if (e->hash == hash && e->pair.key == p_key) {
/* the pair exists in this hashtable, so just update data */
return e;
}
e=e->next;
e = e->next;
}
return NULL;
}
Entry * create_entry(const TKey& p_key) {
Entry *create_entry(const TKey &p_key) {
/* if entry doesn't exist, create it */
Entry *e = memnew( Entry );
ERR_FAIL_COND_V(!e,NULL); /* out of memory */
uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1);
Entry *e = memnew(Entry);
ERR_FAIL_COND_V(!e, NULL); /* out of memory */
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
e->next = hash_table[index];
e->hash = hash;
e->pair.key=p_key;
e->pair.key = p_key;
hash_table[index]=e;
hash_table[index] = e;
elements++;
return e;
}
void copy_from(const HashMap &p_t) {
void copy_from(const HashMap& p_t) {
if (&p_t==this)
if (&p_t == this)
return; /* much less bother with that */
clear();
if (!p_t.hash_table || p_t.hash_table_power==0)
if (!p_t.hash_table || p_t.hash_table_power == 0)
return; /* not copying from empty table */
hash_table = memnew_arr(Entry*,1<<p_t.hash_table_power);
hash_table_power=p_t.hash_table_power;
elements=p_t.elements;
hash_table = memnew_arr(Entry *, 1 << p_t.hash_table_power);
hash_table_power = p_t.hash_table_power;
elements = p_t.elements;
for (int i=0;i<( 1<<p_t.hash_table_power );i++) {
for (int i = 0; i < (1 << p_t.hash_table_power); i++) {
hash_table[i]=NULL;
hash_table[i] = NULL;
/* elements will be in the reverse order, but it doesn't matter */
const Entry *e = p_t.hash_table[i];
while(e) {
while (e) {
Entry *le = memnew( Entry ); /* local entry */
Entry *le = memnew(Entry); /* local entry */
*le=*e; /* copy data */
*le = *e; /* copy data */
/* add to list and reassign pointers */
le->next=hash_table[i];
hash_table[i]=le;
le->next = hash_table[i];
hash_table[i] = le;
e=e->next;
e = e->next;
}
}
}
public:
void set(const TKey &p_key, const TData &p_data) {
void set( const TKey& p_key, const TData& p_data ) {
set( Pair( p_key, p_data ) );
set(Pair(p_key, p_data));
}
void set( const Pair& p_pair ) {
void set(const Pair &p_pair) {
Entry *e=NULL;
Entry *e = NULL;
if (!hash_table)
make_hash_table(); // if no table, make one
else
e = const_cast<Entry*>( get_entry(p_pair.key) );
e = const_cast<Entry *>(get_entry(p_pair.key));
/* if we made it up to here, the pair doesn't exist, create and assign */
if (!e) {
e=create_entry(p_pair.key);
e = create_entry(p_pair.key);
if (!e)
return;
check_hash_table(); // perform mantenience routine
}
e->pair.data = p_pair.data;
}
bool has(const TKey &p_key) const {
bool has( const TKey& p_key ) const {
return getptr(p_key)!=NULL;
return getptr(p_key) != NULL;
}
/**
@@ -318,17 +303,17 @@ public:
* first with has(key)
*/
const TData& get( const TKey& p_key ) const {
const TData &get(const TKey &p_key) const {
const TData* res = getptr(p_key);
ERR_FAIL_COND_V(!res,*res);
const TData *res = getptr(p_key);
ERR_FAIL_COND_V(!res, *res);
return *res;
}
TData& get( const TKey& p_key ) {
TData &get(const TKey &p_key) {
TData* res = getptr(p_key);
ERR_FAIL_COND_V(!res,*res);
TData *res = getptr(p_key);
ERR_FAIL_COND_V(!res, *res);
return *res;
}
@@ -337,33 +322,30 @@ public:
* This is mainly used for speed purposes.
*/
_FORCE_INLINE_ TData* getptr( const TKey& p_key ) {
_FORCE_INLINE_ TData *getptr(const TKey &p_key) {
if (!hash_table)
return NULL;
Entry *e=const_cast<Entry*>(get_entry(p_key ));
Entry *e = const_cast<Entry *>(get_entry(p_key));
if (e)
return &e->pair.data;
return NULL;
}
_FORCE_INLINE_ const TData* getptr( const TKey& p_key ) const {
_FORCE_INLINE_ const TData *getptr(const TKey &p_key) const {
if (!hash_table)
return NULL;
const Entry *e=const_cast<Entry*>(get_entry(p_key ));
const Entry *e = const_cast<Entry *>(get_entry(p_key));
if (e)
return &e->pair.data;
return NULL;
}
/**
@@ -371,129 +353,124 @@ public:
* This version is custom, will take a hash and a custom key (that should support operator==()
*/
template<class C>
_FORCE_INLINE_ TData* custom_getptr( C p_custom_key,uint32_t p_custom_hash ) {
template <class C>
_FORCE_INLINE_ TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) {
if (!hash_table)
return NULL;
uint32_t hash = p_custom_hash;
uint32_t index = hash&((1<<hash_table_power)-1);
uint32_t index = hash & ((1 << hash_table_power) - 1);
Entry *e = hash_table[index];
while (e) {
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_custom_key ) {
if (e->hash == hash && e->pair.key == p_custom_key) {
/* the pair exists in this hashtable, so just update data */
return &e->pair.data;
}
e=e->next;
e = e->next;
}
return NULL;
}
template<class C>
_FORCE_INLINE_ const TData* custom_getptr( C p_custom_key,uint32_t p_custom_hash ) const {
template <class C>
_FORCE_INLINE_ const TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) const {
if (!hash_table)
return NULL;
uint32_t hash = p_custom_hash;
uint32_t index = hash&((1<<hash_table_power)-1);
uint32_t index = hash & ((1 << hash_table_power) - 1);
const Entry *e = hash_table[index];
while (e) {
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_custom_key ) {
if (e->hash == hash && e->pair.key == p_custom_key) {
/* the pair exists in this hashtable, so just update data */
return &e->pair.data;
}
e=e->next;
e = e->next;
}
return NULL;
}
/**
* Erase an item, return true if erasing was succesful
*/
bool erase( const TKey& p_key ) {
bool erase(const TKey &p_key) {
if (!hash_table)
return false;
uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1);
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
Entry *e = hash_table[index];
Entry *p=NULL;
Entry *p = NULL;
while (e) {
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_key ) {
if (e->hash == hash && e->pair.key == p_key) {
if (p) {
p->next=e->next;
p->next = e->next;
} else {
//begin of list
hash_table[index]=e->next;
hash_table[index] = e->next;
}
memdelete(e);
elements--;
if (elements==0)
if (elements == 0)
erase_hash_table();
else
check_hash_table();
return true;
}
p=e;
e=e->next;
p = e;
e = e->next;
}
return false;
}
inline const TData& operator[](const TKey& p_key) const { //constref
inline const TData &operator[](const TKey &p_key) const { //constref
return get(p_key);
}
inline TData& operator[](const TKey& p_key ) { //assignment
inline TData &operator[](const TKey &p_key) { //assignment
Entry *e=NULL;
Entry *e = NULL;
if (!hash_table)
make_hash_table(); // if no table, make one
else
e = const_cast<Entry*>( get_entry(p_key) );
e = const_cast<Entry *>(get_entry(p_key));
/* if we made it up to here, the pair doesn't exist, create */
if (!e) {
e=create_entry(p_key);
e = create_entry(p_key);
if (!e)
return *(TData*)NULL; /* panic! */
return *(TData *)NULL; /* panic! */
check_hash_table(); // perform mantenience routine
}
return e->pair.data;
}
/**
@@ -511,13 +488,13 @@ public:
* }
*
*/
const TKey* next(const TKey* p_key) const {
const TKey *next(const TKey *p_key) const {
if (!hash_table) return NULL;
if (!p_key) { /* get the first key */
for (int i=0;i<(1<<hash_table_power);i++) {
for (int i = 0; i < (1 << hash_table_power); i++) {
if (hash_table[i]) {
return &hash_table[i]->pair.key;
@@ -526,17 +503,17 @@ public:
} else { /* get the next key */
const Entry *e = get_entry( *p_key );
ERR_FAIL_COND_V( !e, NULL ); /* invalid key supplied */
const Entry *e = get_entry(*p_key);
ERR_FAIL_COND_V(!e, NULL); /* invalid key supplied */
if (e->next) {
/* if there is a "next" in the list, return that */
return &e->next->pair.key;
} else {
/* go to next entries */
uint32_t index = e->hash&((1<<hash_table_power)-1);
uint32_t index = e->hash & ((1 << hash_table_power) - 1);
index++;
for (int i=index;i<(1<<hash_table_power);i++) {
for (int i = index; i < (1 << hash_table_power); i++) {
if (hash_table[i]) {
return &hash_table[i]->pair.key;
@@ -545,10 +522,8 @@ public:
}
/* nothing found, was at end */
}
return NULL; /* nothing found */
}
@@ -559,71 +534,68 @@ public:
inline bool empty() const {
return elements==0;
return elements == 0;
}
void clear() {
/* clean up */
if (hash_table) {
for (int i=0;i<(1<<hash_table_power);i++) {
for (int i = 0; i < (1 << hash_table_power); i++) {
while (hash_table[i]) {
Entry *e=hash_table[i];
hash_table[i]=e->next;
memdelete( e );
Entry *e = hash_table[i];
hash_table[i] = e->next;
memdelete(e);
}
}
memdelete_arr( hash_table );
memdelete_arr(hash_table);
}
hash_table=0;
hash_table_power=0;
elements=0;
hash_table = 0;
hash_table_power = 0;
elements = 0;
}
void operator=(const HashMap& p_table) {
void operator=(const HashMap &p_table) {
copy_from(p_table);
}
HashMap() {
hash_table=NULL;
elements=0;
hash_table_power=0;
hash_table = NULL;
elements = 0;
hash_table_power = 0;
}
void get_key_list(List<TKey> *p_keys) const {
if (!hash_table)
return;
for(int i=0;i<(1<<hash_table_power);i++) {
for (int i = 0; i < (1 << hash_table_power); i++) {
Entry *e=hash_table[i];
while(e) {
Entry *e = hash_table[i];
while (e) {
p_keys->push_back(e->pair.key);
e=e->next;
e = e->next;
}
}
}
HashMap(const HashMap& p_table) {
HashMap(const HashMap &p_table) {
hash_table=NULL;
elements=0;
hash_table_power=0;
hash_table = NULL;
elements = 0;
hash_table_power = 0;
copy_from(p_table);
}
~HashMap() {
clear();
}
};
#endif

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,14 +30,12 @@
#ifndef HASHFUNCS_H
#define HASHFUNCS_H
#include "typedefs.h"
/**
* Hashing functions
*/
/**
* DJB2 Hash function
* @param C String
@@ -44,7 +43,7 @@
*/
static inline uint32_t hash_djb2(const char *p_cstr) {
const unsigned char* chr=(const unsigned char*)p_cstr;
const unsigned char *chr = (const unsigned char *)p_cstr;
uint32_t hash = 5381;
uint32_t c;
@@ -54,63 +53,64 @@ static inline uint32_t hash_djb2(const char *p_cstr) {
return hash;
}
static inline uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len,uint32_t p_prev=5381) {
static inline uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len, uint32_t p_prev = 5381) {
uint32_t hash = p_prev;
for(int i=0;i<p_len;i++)
for (int i = 0; i < p_len; i++)
hash = ((hash << 5) + hash) + p_buff[i]; /* hash * 33 + c */
return hash;
}
static inline uint32_t hash_djb2_one_32(uint32_t p_in,uint32_t p_prev=5381) {
static inline uint32_t hash_djb2_one_32(uint32_t p_in, uint32_t p_prev = 5381) {
return ((p_prev<<5)+p_prev)+p_in;
return ((p_prev << 5) + p_prev) + p_in;
}
static inline uint32_t hash_djb2_one_float(float p_in,uint32_t p_prev=5381) {
static inline uint32_t hash_djb2_one_float(float p_in, uint32_t p_prev = 5381) {
union {
float f;
uint32_t i;
} u;
u.f=p_in;
return ((p_prev<<5)+p_prev)+u.i;
// handle -0 case
if (p_in == 0.0f)
u.f = 0.0f;
else
u.f = p_in;
return ((p_prev << 5) + p_prev) + u.i;
}
template<class T>
template <class T>
static inline uint32_t make_uint32_t(T p_in) {
union {
T t;
uint32_t _u32;
} _u;
_u._u32=0;
_u.t=p_in;
_u._u32 = 0;
_u.t = p_in;
return _u._u32;
}
static inline uint64_t hash_djb2_one_64(uint64_t p_in, uint64_t p_prev = 5381) {
static inline uint64_t hash_djb2_one_64(uint64_t p_in,uint64_t p_prev=5381) {
return ((p_prev<<5)+p_prev)+p_in;
return ((p_prev << 5) + p_prev) + p_in;
}
template<class T>
template <class T>
static inline uint64_t make_uint64_t(T p_in) {
union {
T t;
uint64_t _u64;
} _u;
_u._u64=0; // in case p_in is smaller
_u._u64 = 0; // in case p_in is smaller
_u.t=p_in;
_u.t = p_in;
return _u._u64;
}
#endif

7
core/helper/SCsub Normal file
View File

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

View File

@@ -0,0 +1,136 @@
/*************************************************************************/
/* fieldwise.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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. */
/*************************************************************************/
#ifdef TOOLS_ENABLED
#include "core/helper/math_fieldwise.h"
#define SETUP_TYPE(m_type) \
m_type source = p_source; \
m_type target = p_target;
#define TRY_TRANSFER_FIELD(m_name, m_member) \
if (p_field == m_name) { \
target.m_member = source.m_member; \
}
Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const String &p_field) {
ERR_FAIL_COND_V(p_target.get_type() != p_source.get_type(), p_target);
switch (p_source.get_type()) {
case Variant::VECTOR2: {
SETUP_TYPE(Vector2)
/**/ TRY_TRANSFER_FIELD("x", x) else TRY_TRANSFER_FIELD("y", y)
return target;
}
case Variant::RECT2: {
SETUP_TYPE(Rect2)
/**/ TRY_TRANSFER_FIELD("x", pos.x) else TRY_TRANSFER_FIELD("y", pos.y) else TRY_TRANSFER_FIELD("w", size.x) else TRY_TRANSFER_FIELD("h", size.y)
return target;
}
case Variant::VECTOR3: {
SETUP_TYPE(Vector3)
/**/ TRY_TRANSFER_FIELD("x", x) else TRY_TRANSFER_FIELD("y", y) else TRY_TRANSFER_FIELD("z", z)
return target;
}
case Variant::PLANE: {
SETUP_TYPE(Plane)
/**/ TRY_TRANSFER_FIELD("x", normal.x) else TRY_TRANSFER_FIELD("y", normal.y) else TRY_TRANSFER_FIELD("z", normal.z) else TRY_TRANSFER_FIELD("d", d)
return target;
}
case Variant::QUAT: {
SETUP_TYPE(Quat)
/**/ TRY_TRANSFER_FIELD("x", x) else TRY_TRANSFER_FIELD("y", y) else TRY_TRANSFER_FIELD("z", z) else TRY_TRANSFER_FIELD("w", w)
return target;
}
case Variant::_AABB: {
SETUP_TYPE(AABB)
/**/ TRY_TRANSFER_FIELD("px", pos.x) else TRY_TRANSFER_FIELD("py", pos.y) else TRY_TRANSFER_FIELD("pz", pos.z) else TRY_TRANSFER_FIELD("sx", size.x) else TRY_TRANSFER_FIELD("sy", size.y) else TRY_TRANSFER_FIELD("sz", size.z)
return target;
}
case Variant::MATRIX32: {
SETUP_TYPE(Matrix32)
/**/ TRY_TRANSFER_FIELD("xx", elements[0][0]) else TRY_TRANSFER_FIELD("xy", elements[0][1]) else TRY_TRANSFER_FIELD("yx", elements[1][0]) else TRY_TRANSFER_FIELD("yy", elements[1][1]) else TRY_TRANSFER_FIELD("ox", elements[2][0]) else TRY_TRANSFER_FIELD("oy", elements[2][1])
return target;
}
case Variant::MATRIX3: {
SETUP_TYPE(Matrix3)
/**/ TRY_TRANSFER_FIELD("xx", elements[0][0]) else TRY_TRANSFER_FIELD("xy", elements[0][1]) else TRY_TRANSFER_FIELD("xz", elements[0][2]) else TRY_TRANSFER_FIELD("yx", elements[1][0]) else TRY_TRANSFER_FIELD("yy", elements[1][1]) else TRY_TRANSFER_FIELD("yz", elements[1][2]) else TRY_TRANSFER_FIELD("zx", elements[2][0]) else TRY_TRANSFER_FIELD("zy", elements[2][1]) else TRY_TRANSFER_FIELD("zz", elements[2][2])
return target;
}
case Variant::TRANSFORM: {
SETUP_TYPE(Transform)
/**/ TRY_TRANSFER_FIELD("xx", basis.elements[0][0]) else TRY_TRANSFER_FIELD("xy", basis.elements[0][1]) else TRY_TRANSFER_FIELD("xz", basis.elements[0][2]) else TRY_TRANSFER_FIELD("yx", basis.elements[1][0]) else TRY_TRANSFER_FIELD("yy", basis.elements[1][1]) else TRY_TRANSFER_FIELD("yz", basis.elements[1][2]) else TRY_TRANSFER_FIELD("zx", basis.elements[2][0]) else TRY_TRANSFER_FIELD("zy", basis.elements[2][1]) else TRY_TRANSFER_FIELD("zz", basis.elements[2][2]) else TRY_TRANSFER_FIELD("xo", origin.x) else TRY_TRANSFER_FIELD("yo", origin.y) else TRY_TRANSFER_FIELD("zo", origin.z)
return target;
}
default: {
ERR_FAIL_V(p_target);
}
}
}
#endif // TOOLS_ENABLED

View File

@@ -0,0 +1,41 @@
/*************************************************************************/
/* fieldwise.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 MATH_FIELDWISE_H
#define MATH_FIELDWISE_H
#ifdef TOOLS_ENABLED
#include "core/variant.h"
Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const String &p_field);
#endif // TOOLS_ENABLED
#endif // MATH_FIELDWISE_H

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -34,8 +35,9 @@
class ValueEvaluator : public Object {
OBJ_TYPE(ValueEvaluator, Object);
public:
virtual double eval(const String& p_text) {
virtual double eval(const String &p_text) {
return p_text.to_double();
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,8 +30,8 @@
#ifndef IMAGE_H
#define IMAGE_H
#include "dvector.h"
#include "color.h"
#include "dvector.h"
#include "math_2d.h"
/**
* @author Juan Linietsky <reduzio@gmail.com>
@@ -42,16 +43,16 @@
class Image;
typedef Error (*SavePNGFunc)(const String &p_path, Image& p_img);
typedef Error (*SavePNGFunc)(const String &p_path, Image &p_img);
class Image {
enum {
MAX_WIDTH=16384, // force a limit somehow
MAX_HEIGHT=16384// force a limit somehow
MAX_WIDTH = 16384, // force a limit somehow
MAX_HEIGHT = 16384 // force a limit somehow
};
public:
public:
static SavePNGFunc save_png_func;
enum Format {
@@ -87,7 +88,7 @@ public:
FORMAT_MAX
};
static const char* format_names[FORMAT_MAX];
static const char *format_names[FORMAT_MAX];
enum Interpolation {
INTERPOLATE_NEAREST,
@@ -96,8 +97,8 @@ public:
/* INTERPOLATE GAUSS */
};
static Image (*_png_mem_loader_func)(const uint8_t* p_png,int p_size);
static Image (*_jpg_mem_loader_func)(const uint8_t* p_png,int p_size);
static Image (*_png_mem_loader_func)(const uint8_t *p_png, int p_size);
static Image (*_jpg_mem_loader_func)(const uint8_t *p_png, int p_size);
static void (*_image_compress_bc_func)(Image *);
static void (*_image_compress_pvrtc2_func)(Image *);
static void (*_image_compress_pvrtc4_func)(Image *);
@@ -108,25 +109,35 @@ public:
Error _decompress_bc();
static DVector<uint8_t> (*lossy_packer)(const Image& p_image,float p_quality);
static Image (*lossy_unpacker)(const DVector<uint8_t>& p_buffer);
static DVector<uint8_t> (*lossless_packer)(const Image& p_image);
static Image (*lossless_unpacker)(const DVector<uint8_t>& p_buffer);
private:
static DVector<uint8_t> (*lossy_packer)(const Image &p_image, float p_quality);
static Image (*lossy_unpacker)(const DVector<uint8_t> &p_buffer);
static DVector<uint8_t> (*lossless_packer)(const Image &p_image);
static Image (*lossless_unpacker)(const DVector<uint8_t> &p_buffer);
private:
//internal byte based color
struct BColor {
union {
uint8_t col[4];
struct {
uint8_t r,g,b,a;
uint8_t r, g, b, a;
};
};
bool operator==(const BColor& p_color) const { for(int i=0;i<4;i++) {if (col[i]!=p_color.col[i]) return false; } return true; }
_FORCE_INLINE_ uint8_t gray() const { return (uint16_t(col[0])+uint16_t(col[1])+uint16_t(col[2]))/3; }
bool operator==(const BColor &p_color) const {
for (int i = 0; i < 4; i++) {
if (col[i] != p_color.col[i]) return false;
}
return true;
}
_FORCE_INLINE_ uint8_t gray() const { return (uint16_t(col[0]) + uint16_t(col[1]) + uint16_t(col[2])) / 3; }
_FORCE_INLINE_ BColor() {}
BColor(uint8_t p_r,uint8_t p_g,uint8_t p_b,uint8_t p_a=255) { col[0]=p_r; col[1]=p_g; col[2]=p_b; col[3]=p_a; }
BColor(uint8_t p_r, uint8_t p_g, uint8_t p_b, uint8_t p_a = 255) {
col[0] = p_r;
col[1] = p_g;
col[2] = p_b;
col[3] = p_a;
}
};
//median cut classes
@@ -137,22 +148,22 @@ private:
BColor color;
struct SortR {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.r < cb.color.r; }
bool operator()(const BColorPos &ca, const BColorPos &cb) const { return ca.color.r < cb.color.r; }
};
struct SortG {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.g < cb.color.g; }
bool operator()(const BColorPos &ca, const BColorPos &cb) const { return ca.color.g < cb.color.g; }
};
struct SortB {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.b < cb.color.b; }
bool operator()(const BColorPos &ca, const BColorPos &cb) const { return ca.color.b < cb.color.b; }
};
struct SortA {
bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.a < cb.color.a; }
bool operator()(const BColorPos &ca, const BColorPos &cb) const { return ca.color.a < cb.color.a; }
};
};
@@ -166,45 +177,42 @@ private:
int color;
};
int right;
SPTree() { leaf=true; left=-1; right=-1;}
SPTree() {
leaf = true;
left = -1;
right = -1;
}
};
struct MCBlock {
BColorPos min_color,max_color;
BColorPos min_color, max_color;
BColorPos *colors;
int sp_idx;
int color_count;
int get_longest_axis_index() const;
int get_longest_axis_length() const;
bool operator<(const MCBlock& p_block) const;
bool operator<(const MCBlock &p_block) const;
void shrink();
MCBlock();
MCBlock(BColorPos *p_colors,int p_color_count);
MCBlock(BColorPos *p_colors, int p_color_count);
};
Format format;
DVector<uint8_t> data;
int width,height,mipmaps;
int width, height, mipmaps;
_FORCE_INLINE_ BColor _get_pixel(int p_x, int p_y, const unsigned char *p_data, int p_data_size) const;
_FORCE_INLINE_ BColor _get_pixelw(int p_x, int p_y, int p_width, const unsigned char *p_data, int p_data_size) const;
_FORCE_INLINE_ void _put_pixelw(int p_x, int p_y, int p_width, const BColor &p_color, unsigned char *p_data);
_FORCE_INLINE_ void _put_pixel(int p_x, int p_y, const BColor &p_color, unsigned char *p_data);
_FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_width, int &r_height) const; //get where the mipmap begins in data
_FORCE_INLINE_ static void _get_format_min_data_size(Format p_format, int &r_w, int &r_h);
_FORCE_INLINE_ BColor _get_pixel(int p_x,int p_y,const unsigned char *p_data,int p_data_size) const;
_FORCE_INLINE_ BColor _get_pixelw(int p_x,int p_y,int p_width,const unsigned char *p_data,int p_data_size) const;
_FORCE_INLINE_ void _put_pixelw(int p_x,int p_y, int p_width, const BColor& p_color, unsigned char *p_data);
_FORCE_INLINE_ void _put_pixel(int p_x,int p_y, const BColor& p_color, unsigned char *p_data);
_FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap,int &r_offset, int &r_width, int &r_height) const; //get where the mipmap begins in data
_FORCE_INLINE_ static void _get_format_min_data_size(Format p_format,int &r_w, int &r_h);
static int _get_dst_image_size(int p_width, int p_height, Format p_format,int &r_mipmaps,int p_mipmaps=-1);
static int _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1);
bool _can_modify(Format p_format) const;
public:
int get_width() const; ///< Get image width
int get_height() const; ///< Get image height
int get_mipmaps() const;
@@ -213,16 +221,16 @@ public:
* Get a pixel from the image. for grayscale or indexed formats, use Color::gray to obtain the actual
* value.
*/
Color get_pixel(int p_x,int p_y,int p_mipmap=0) const;
Color get_pixel(int p_x, int p_y, int p_mipmap = 0) const;
/**
* Set a pixel into the image. for grayscale or indexed formats, a suitable Color constructor.
*/
void put_pixel(int p_x,int p_y, const Color& p_color,int p_mipmap=0); /* alpha and index are averaged */
void put_pixel(int p_x, int p_y, const Color &p_color, int p_mipmap = 0); /* alpha and index are averaged */
/**
* Convert the image to another format, as close as it can be done.
*/
void convert( Format p_new_format );
void convert(Format p_new_format);
Image converted(int p_new_format) {
ERR_FAIL_INDEX_V(p_new_format, FORMAT_MAX, Image());
@@ -238,48 +246,46 @@ public:
Format get_format() const;
int get_mipmap_offset(int p_mipmap) const; //get where the mipmap begins in data
void get_mipmap_offset_and_size(int p_mipmap,int &r_ofs, int &r_size) const; //get where the mipmap begins in data
void get_mipmap_offset_size_and_dimensions(int p_mipmap,int &r_ofs, int &r_size,int &w, int& h) const; //get where the mipmap begins in data
void get_mipmap_offset_and_size(int p_mipmap, int &r_ofs, int &r_size) const; //get where the mipmap begins in data
void get_mipmap_offset_size_and_dimensions(int p_mipmap, int &r_ofs, int &r_size, int &w, int &h) const; //get where the mipmap begins in data
/**
* Resize the image, using the prefered interpolation method.
* Indexed-Color images always use INTERPOLATE_NEAREST.
*/
void resize_to_po2(bool p_square=false);
void resize( int p_width, int p_height, Interpolation p_interpolation=INTERPOLATE_BILINEAR );
Image resized( int p_width, int p_height, int p_interpolation=INTERPOLATE_BILINEAR );
void resize_to_po2(bool p_square = false);
void resize(int p_width, int p_height, Interpolation p_interpolation = INTERPOLATE_BILINEAR);
Image resized(int p_width, int p_height, int p_interpolation = INTERPOLATE_BILINEAR);
void shrink_x2();
void expand_x2_hq2x();
/**
* Crop the image to a specific size, if larger, then the image is filled by black
*/
void crop( int p_width, int p_height );
void crop(int p_width, int p_height);
void flip_x();
void flip_y();
/**
* Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1)
*/
Error generate_mipmaps(int p_amount=-1,bool p_keep_existing=false);
Error generate_mipmaps(int p_amount = -1, bool p_keep_existing = false);
void clear_mipmaps();
/**
* Generate a normal map from a grayscale image
*/
void make_normalmap(float p_height_scale=1.0);
void make_normalmap(float p_height_scale = 1.0);
/**
* Create a new image of a given size and format. Current image will be lost
*/
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
void create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
void create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t> &p_data);
void create( const char ** p_xpm );
void create(const char **p_xpm);
/**
* returns true when the image is empty (0,0) in size
*/
@@ -287,8 +293,8 @@ public:
DVector<uint8_t> get_data() const;
Error load(const String& p_path);
Error save_png(const String& p_path);
Error load(const String &p_path);
Error save_png(const String &p_path);
/**
* create an empty image
@@ -301,7 +307,7 @@ public:
/**
* import an image of a specific size and format from a pointer
*/
Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t> &p_data);
enum AlphaMode {
ALPHA_NONE,
@@ -312,21 +318,17 @@ public:
AlphaMode detect_alpha() const;
bool is_invisible() const;
void put_indexed_pixel(int p_x, int p_y, uint8_t p_idx,int p_mipmap=0);
uint8_t get_indexed_pixel(int p_x, int p_y,int p_mipmap=0) const;
void set_pallete(const DVector<uint8_t>& p_data);
void put_indexed_pixel(int p_x, int p_y, uint8_t p_idx, int p_mipmap = 0);
uint8_t get_indexed_pixel(int p_x, int p_y, int p_mipmap = 0) const;
void set_pallete(const DVector<uint8_t> &p_data);
static int get_format_pixel_size(Format p_format);
static int get_format_pixel_rshift(Format p_format);
static int get_format_pallete_size(Format p_format);
static int get_image_data_size(int p_width, int p_height, Format p_format,int p_mipmaps=0);
static int get_image_data_size(int p_width, int p_height, Format p_format, int p_mipmaps = 0);
static int get_image_required_mipmaps(int p_width, int p_height, Format p_format);
bool operator==(const Image& p_image) const;
bool operator==(const Image &p_image) const;
void quantize();
@@ -337,7 +339,7 @@ public:
COMPRESS_ETC
};
Error compress(CompressMode p_mode=COMPRESS_BC);
Error compress(CompressMode p_mode = COMPRESS_BC);
Image compressed(int p_mode); /* from the Image::CompressMode enum */
Error decompress();
Image decompressed() const;
@@ -348,21 +350,19 @@ public:
void srgb_to_linear();
void normalmap_to_xy();
void blit_rect(const Image& p_src, const Rect2& p_src_rect,const Point2& p_dest);
void brush_transfer(const Image& p_src, const Image& p_brush, const Point2& p_dest);
Image brushed(const Image& p_src, const Image& p_brush, const Point2& p_dest) const;
void blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
void brush_transfer(const Image &p_src, const Image &p_brush, const Point2 &p_dest);
Image brushed(const Image &p_src, const Image &p_brush, const Point2 &p_dest) const;
Rect2 get_used_rect() const;
Image get_rect(const Rect2& p_area) const;
Image get_rect(const Rect2 &p_area) const;
static void set_compress_bc_func(void (*p_compress_func)(Image *));
static String get_format_name(Format p_format);
Image(const uint8_t* p_mem_png_jpg, int p_len=-1);
Image(const uint8_t *p_mem_png_jpg, int p_len = -1);
Image(const char **p_xpm);
~Image();
};
#endif

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -27,41 +28,38 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "image.h"
#include <stdio.h>
#include "print_string.h"
#include <stdio.h>
#ifdef TOOLS_ENABLED
#include "os/os.h"
#include "set.h"
#include "sort.h"
#include "os/os.h"
//#define QUANTIZE_SPEED_OVER_QUALITY
Image::MCBlock::MCBlock() {
}
Image::MCBlock::MCBlock(BColorPos *p_colors,int p_color_count) {
Image::MCBlock::MCBlock(BColorPos *p_colors, int p_color_count) {
colors=p_colors;
color_count=p_color_count;
min_color.color=BColor(255,255,255,255);
max_color.color=BColor(0,0,0,0);
colors = p_colors;
color_count = p_color_count;
min_color.color = BColor(255, 255, 255, 255);
max_color.color = BColor(0, 0, 0, 0);
shrink();
}
int Image::MCBlock::get_longest_axis_index() const {
int max_dist=-1;
int max_index=0;
int max_dist = -1;
int max_index = 0;
for(int i=0;i<4;i++) {
for (int i = 0; i < 4; i++) {
int d = max_color.color.col[i]-min_color.color.col[i];
if (d>max_dist) {
max_index=i;
max_dist=d;
int d = max_color.color.col[i] - min_color.color.col[i];
if (d > max_dist) {
max_index = i;
max_dist = d;
}
}
@@ -69,88 +67,80 @@ int Image::MCBlock::get_longest_axis_index() const {
}
int Image::MCBlock::get_longest_axis_length() const {
int max_dist=-1;
int max_dist = -1;
for(int i=0;i<4;i++) {
for (int i = 0; i < 4; i++) {
int d = max_color.color.col[i]-min_color.color.col[i];
if (d>max_dist) {
max_dist=d;
int d = max_color.color.col[i] - min_color.color.col[i];
if (d > max_dist) {
max_dist = d;
}
}
return max_dist;
}
bool Image::MCBlock::operator<(const MCBlock& p_block) const {
bool Image::MCBlock::operator<(const MCBlock &p_block) const {
int alen = get_longest_axis_length();
int blen = p_block.get_longest_axis_length();
if (alen==blen) {
if (alen == blen) {
return colors < p_block.colors;
} else
return alen < blen;
}
void Image::MCBlock::shrink() {
min_color=colors[0];
max_color=colors[0];
min_color = colors[0];
max_color = colors[0];
for(int i=1;i<color_count;i++) {
for (int i = 1; i < color_count; i++) {
for(int j=0;j<4;j++) {
for (int j = 0; j < 4; j++) {
min_color.color.col[j]=MIN(min_color.color.col[j],colors[i].color.col[j]);
max_color.color.col[j]=MAX(max_color.color.col[j],colors[i].color.col[j]);
min_color.color.col[j] = MIN(min_color.color.col[j], colors[i].color.col[j]);
max_color.color.col[j] = MAX(max_color.color.col[j], colors[i].color.col[j]);
}
}
}
void Image::quantize() {
bool has_alpha = detect_alpha()!=ALPHA_NONE;
bool has_alpha = detect_alpha() != ALPHA_NONE;
bool quantize_fast=OS::get_singleton()->has_environment("QUANTIZE_FAST");
bool quantize_fast = OS::get_singleton()->has_environment("QUANTIZE_FAST");
convert(FORMAT_RGBA);
ERR_FAIL_COND( format!=FORMAT_RGBA );
ERR_FAIL_COND(format != FORMAT_RGBA);
DVector<uint8_t> indexed_data;
{
int color_count = data.size()/4;
int color_count = data.size() / 4;
ERR_FAIL_COND(color_count==0);
ERR_FAIL_COND(color_count == 0);
Set<MCBlock> block_queue;
DVector<BColorPos> data_colors;
data_colors.resize(color_count);
DVector<BColorPos>::Write dcw=data_colors.write();
DVector<BColorPos>::Write dcw = data_colors.write();
DVector<uint8_t>::Read dr = data.read();
const BColor * drptr=(const BColor*)&dr[0];
BColorPos *bcptr=&dcw[0];
const BColor *drptr = (const BColor *)&dr[0];
BColorPos *bcptr = &dcw[0];
{
for(int i=0;i<color_count;i++) {
for (int i = 0; i < color_count; i++) {
//uint32_t data_ofs=i<<2;
bcptr[i].color=drptr[i];//BColor(drptr[data_ofs+0],drptr[data_ofs+1],drptr[data_ofs+2],drptr[data_ofs+3]);
bcptr[i].index=i;
bcptr[i].color = drptr[i]; //BColor(drptr[data_ofs+0],drptr[data_ofs+1],drptr[data_ofs+2],drptr[data_ofs+3]);
bcptr[i].index = i;
}
}
//printf("color count: %i\n",color_count);
@@ -161,11 +151,11 @@ void Image::quantize() {
printf("%i - %i,%i,%i,%i\n",i,bc.r,bc.g,bc.b,bc.a);
}*/
MCBlock initial_block((BColorPos*)&dcw[0],color_count);
MCBlock initial_block((BColorPos *)&dcw[0], color_count);
block_queue.insert(initial_block);
while( block_queue.size() < 256 && block_queue.back()->get().color_count > 1 ) {
while (block_queue.size() < 256 && block_queue.back()->get().color_count > 1) {
MCBlock longest = block_queue.back()->get();
//printf("longest: %i (%i)\n",longest.get_longest_axis_index(),longest.get_longest_axis_length());
@@ -173,7 +163,7 @@ void Image::quantize() {
block_queue.erase(block_queue.back());
BColorPos *first = longest.colors;
BColorPos *median = longest.colors + (longest.color_count+1)/2;
BColorPos *median = longest.colors + (longest.color_count + 1) / 2;
BColorPos *end = longest.colors + longest.color_count;
#if 0
@@ -234,111 +224,122 @@ void Image::quantize() {
block_queue.insert(right);
#else
switch(longest.get_longest_axis_index()) {
case 0: { SortArray<BColorPos,BColorPos::SortR> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 1: { SortArray<BColorPos,BColorPos::SortG> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 2: { SortArray<BColorPos,BColorPos::SortB> sort; sort.nth_element(0,end-first,median-first,first); } break;
case 3: { SortArray<BColorPos,BColorPos::SortA> sort; sort.nth_element(0,end-first,median-first,first); } break;
switch (longest.get_longest_axis_index()) {
case 0: {
SortArray<BColorPos, BColorPos::SortR> sort;
sort.nth_element(0, end - first, median - first, first);
} break;
case 1: {
SortArray<BColorPos, BColorPos::SortG> sort;
sort.nth_element(0, end - first, median - first, first);
} break;
case 2: {
SortArray<BColorPos, BColorPos::SortB> sort;
sort.nth_element(0, end - first, median - first, first);
} break;
case 3: {
SortArray<BColorPos, BColorPos::SortA> sort;
sort.nth_element(0, end - first, median - first, first);
} break;
}
MCBlock left(first,median-first);
MCBlock right(median,end-median);
MCBlock left(first, median - first);
MCBlock right(median, end - median);
block_queue.insert(left);
block_queue.insert(right);
#endif
}
while(block_queue.size() > 256) {
while (block_queue.size() > 256) {
block_queue.erase(block_queue.front());// erase least significant
block_queue.erase(block_queue.front()); // erase least significant
}
int res_colors=0;
int res_colors = 0;
int comp_size = (has_alpha?4:3);
indexed_data.resize(color_count + 256*comp_size);
int comp_size = (has_alpha ? 4 : 3);
indexed_data.resize(color_count + 256 * comp_size);
DVector<uint8_t>::Write iw = indexed_data.write();
uint8_t *iwptr=&iw[0];
uint8_t *iwptr = &iw[0];
BColor pallete[256];
// print_line("applying quantization - res colors "+itos(block_queue.size()));
// print_line("applying quantization - res colors "+itos(block_queue.size()));
while(block_queue.size()) {
while (block_queue.size()) {
const MCBlock &b = block_queue.back()->get();
uint64_t sum[4]={0,0,0,0};
uint64_t sum[4] = { 0, 0, 0, 0 };
for(int i=0;i<b.color_count;i++) {
for (int i = 0; i < b.color_count; i++) {
sum[0]+=b.colors[i].color.col[0];
sum[1]+=b.colors[i].color.col[1];
sum[2]+=b.colors[i].color.col[2];
sum[3]+=b.colors[i].color.col[3];
sum[0] += b.colors[i].color.col[0];
sum[1] += b.colors[i].color.col[1];
sum[2] += b.colors[i].color.col[2];
sum[3] += b.colors[i].color.col[3];
}
BColor c( sum[0]/b.color_count, sum[1]/b.color_count, sum[2]/b.color_count, sum[3]/b.color_count );
BColor c(sum[0] / b.color_count, sum[1] / b.color_count, sum[2] / b.color_count, sum[3] / b.color_count);
//printf(" %i: %i,%i,%i,%i out of %i\n",res_colors,c.r,c.g,c.b,c.a,b.color_count);
for(int i=0;i<comp_size;i++) {
iwptr[ color_count + res_colors * comp_size + i ] = c.col[i];
for (int i = 0; i < comp_size; i++) {
iwptr[color_count + res_colors * comp_size + i] = c.col[i];
}
if (quantize_fast) {
for(int i=0;i<b.color_count;i++) {
iwptr[b.colors[i].index]=res_colors;
for (int i = 0; i < b.color_count; i++) {
iwptr[b.colors[i].index] = res_colors;
}
} else {
pallete[res_colors]=c;
pallete[res_colors] = c;
}
res_colors++;
block_queue.erase(block_queue.back());
}
if (!quantize_fast) {
for(int i=0;i<color_count;i++) {
for (int i = 0; i < color_count; i++) {
const BColor &c=drptr[i];
uint8_t best_dist_idx=0;
uint32_t dist=0xFFFFFFFF;
const BColor &c = drptr[i];
uint8_t best_dist_idx = 0;
uint32_t dist = 0xFFFFFFFF;
for(int j=0;j<res_colors;j++) {
for (int j = 0; j < res_colors; j++) {
const BColor &pc=pallete[j];
const BColor &pc = pallete[j];
uint32_t d = 0;
{ int16_t v = (int16_t)c.r-(int16_t)pc.r; d+=v*v; }
{ int16_t v = (int16_t)c.g-(int16_t)pc.g; d+=v*v; }
{ int16_t v = (int16_t)c.b-(int16_t)pc.b; d+=v*v; }
{ int16_t v = (int16_t)c.a-(int16_t)pc.a; d+=v*v; }
{
int16_t v = (int16_t)c.r - (int16_t)pc.r;
d += v * v;
}
{
int16_t v = (int16_t)c.g - (int16_t)pc.g;
d += v * v;
}
{
int16_t v = (int16_t)c.b - (int16_t)pc.b;
d += v * v;
}
{
int16_t v = (int16_t)c.a - (int16_t)pc.a;
d += v * v;
}
if (d<=dist) {
best_dist_idx=j;
dist=d;
if (d <= dist) {
best_dist_idx = j;
dist = d;
}
}
iwptr[ i ] = best_dist_idx;
iwptr[i] = best_dist_idx;
}
}
@@ -348,18 +349,13 @@ void Image::quantize() {
}
print_line(itos(indexed_data.size()));
data=indexed_data;
format=has_alpha?FORMAT_INDEXED_ALPHA:FORMAT_INDEXED;
data = indexed_data;
format = has_alpha ? FORMAT_INDEXED_ALPHA : FORMAT_INDEXED;
} //do none
#else
void Image::quantize() {} //do none
#endif

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -30,50 +31,45 @@
#include "globals.h"
#include "os/keyboard.h"
InputMap *InputMap::singleton=NULL;
InputMap *InputMap::singleton = NULL;
void InputMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("has_action","action"),&InputMap::has_action);
ObjectTypeDB::bind_method(_MD("get_action_id","action"),&InputMap::get_action_id);
ObjectTypeDB::bind_method(_MD("get_action_from_id","id"),&InputMap::get_action_from_id);
ObjectTypeDB::bind_method(_MD("get_actions"),&InputMap::_get_actions);
ObjectTypeDB::bind_method(_MD("add_action","action"),&InputMap::add_action);
ObjectTypeDB::bind_method(_MD("erase_action","action"),&InputMap::erase_action);
ObjectTypeDB::bind_method(_MD("action_add_event","action","event"),&InputMap::action_add_event);
ObjectTypeDB::bind_method(_MD("action_has_event","action","event"),&InputMap::action_has_event);
ObjectTypeDB::bind_method(_MD("action_erase_event","action","event"),&InputMap::action_erase_event);
ObjectTypeDB::bind_method(_MD("get_action_list","action"),&InputMap::_get_action_list);
ObjectTypeDB::bind_method(_MD("event_is_action","event","action"),&InputMap::event_is_action);
ObjectTypeDB::bind_method(_MD("load_from_globals"),&InputMap::load_from_globals);
ObjectTypeDB::bind_method(_MD("has_action", "action"), &InputMap::has_action);
ObjectTypeDB::bind_method(_MD("get_action_id", "action"), &InputMap::get_action_id);
ObjectTypeDB::bind_method(_MD("get_action_from_id", "id"), &InputMap::get_action_from_id);
ObjectTypeDB::bind_method(_MD("get_actions"), &InputMap::_get_actions);
ObjectTypeDB::bind_method(_MD("add_action", "action"), &InputMap::add_action);
ObjectTypeDB::bind_method(_MD("erase_action", "action"), &InputMap::erase_action);
ObjectTypeDB::bind_method(_MD("action_add_event", "action", "event"), &InputMap::action_add_event);
ObjectTypeDB::bind_method(_MD("action_has_event", "action", "event"), &InputMap::action_has_event);
ObjectTypeDB::bind_method(_MD("action_erase_event", "action", "event"), &InputMap::action_erase_event);
ObjectTypeDB::bind_method(_MD("get_action_list", "action"), &InputMap::_get_action_list);
ObjectTypeDB::bind_method(_MD("event_is_action", "event", "action"), &InputMap::event_is_action);
ObjectTypeDB::bind_method(_MD("load_from_globals"), &InputMap::load_from_globals);
}
void InputMap::add_action(const StringName &p_action) {
void InputMap::add_action(const StringName& p_action) {
ERR_FAIL_COND( input_map.has(p_action) );
input_map[p_action]=Action();
static int last_id=1;
input_map[p_action].id=last_id;
input_id_map[last_id]=p_action;
ERR_FAIL_COND(input_map.has(p_action));
input_map[p_action] = Action();
static int last_id = 1;
input_map[p_action].id = last_id;
input_id_map[last_id] = p_action;
last_id++;
}
void InputMap::erase_action(const StringName& p_action) {
void InputMap::erase_action(const StringName &p_action) {
ERR_FAIL_COND( !input_map.has(p_action) );
ERR_FAIL_COND(!input_map.has(p_action));
input_id_map.erase(input_map[p_action].id);
input_map.erase(p_action);
}
StringName InputMap::get_action_from_id(int p_id) const {
ERR_FAIL_COND_V(!input_id_map.has(p_id),StringName());
ERR_FAIL_COND_V(!input_id_map.has(p_id), StringName());
return input_id_map[p_id];
}
@@ -81,10 +77,10 @@ Array InputMap::_get_actions() {
Array ret;
List<StringName> actions = get_actions();
if(actions.empty())
if (actions.empty())
return ret;
for(const List<StringName>::Element *E=actions.front();E;E=E->next()) {
for (const List<StringName>::Element *E = actions.front(); E; E = E->next()) {
ret.push_back(E->get());
}
@@ -95,49 +91,49 @@ Array InputMap::_get_actions() {
List<StringName> InputMap::get_actions() const {
List<StringName> actions = List<StringName>();
if(input_map.empty()){
if (input_map.empty()) {
return actions;
}
for (Map<StringName, Action>::Element *E=input_map.front();E;E=E->next()) {
for (Map<StringName, Action>::Element *E = input_map.front(); E; E = E->next()) {
actions.push_back(E->key());
}
return actions;
}
List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const {
List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list, const InputEvent &p_event) const {
for (List<InputEvent>::Element *E=p_list.front();E;E=E->next()) {
for (List<InputEvent>::Element *E = p_list.front(); E; E = E->next()) {
const InputEvent& e=E->get();
if(e.type!=p_event.type)
const InputEvent &e = E->get();
if (e.type != p_event.type)
continue;
if (e.type!=InputEvent::KEY && e.device!=p_event.device)
if (e.type != InputEvent::KEY && e.device != p_event.device)
continue;
bool same=false;
bool same = false;
switch(p_event.type) {
switch (p_event.type) {
case InputEvent::KEY: {
same=(e.key.scancode==p_event.key.scancode && e.key.mod == p_event.key.mod);
same = (e.key.scancode == p_event.key.scancode && e.key.mod == p_event.key.mod);
} break;
case InputEvent::JOYSTICK_BUTTON: {
same=(e.joy_button.button_index==p_event.joy_button.button_index);
same = (e.joy_button.button_index == p_event.joy_button.button_index);
} break;
case InputEvent::MOUSE_BUTTON: {
same=(e.mouse_button.button_index==p_event.mouse_button.button_index);
same = (e.mouse_button.button_index == p_event.mouse_button.button_index);
} break;
case InputEvent::JOYSTICK_MOTION: {
same=(e.joy_motion.axis==p_event.joy_motion.axis && (e.joy_motion.axis_value < 0) == (p_event.joy_motion.axis_value < 0));
same = (e.joy_motion.axis == p_event.joy_motion.axis && (e.joy_motion.axis_value < 0) == (p_event.joy_motion.axis_value < 0));
} break;
}
@@ -146,245 +142,173 @@ List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list,const
return E;
}
return NULL;
}
bool InputMap::has_action(const StringName& p_action) const {
bool InputMap::has_action(const StringName &p_action) const {
return input_map.has(p_action);
}
void InputMap::action_add_event(const StringName& p_action,const InputEvent& p_event) {
void InputMap::action_add_event(const StringName &p_action, const InputEvent &p_event) {
ERR_FAIL_COND(p_event.type==InputEvent::ACTION);
ERR_FAIL_COND( !input_map.has(p_action) );
if (_find_event(input_map[p_action].inputs,p_event))
ERR_FAIL_COND(p_event.type == InputEvent::ACTION);
ERR_FAIL_COND(!input_map.has(p_action));
if (_find_event(input_map[p_action].inputs, p_event))
return; //already gots
input_map[p_action].inputs.push_back(p_event);
}
int InputMap::get_action_id(const StringName &p_action) const {
int InputMap::get_action_id(const StringName& p_action) const {
ERR_FAIL_COND_V(!input_map.has(p_action),-1);
ERR_FAIL_COND_V(!input_map.has(p_action), -1);
return input_map[p_action].id;
}
bool InputMap::action_has_event(const StringName& p_action,const InputEvent& p_event) {
ERR_FAIL_COND_V( !input_map.has(p_action), false );
return (_find_event(input_map[p_action].inputs,p_event)!=NULL);
bool InputMap::action_has_event(const StringName &p_action, const InputEvent &p_event) {
ERR_FAIL_COND_V(!input_map.has(p_action), false);
return (_find_event(input_map[p_action].inputs, p_event) != NULL);
}
void InputMap::action_erase_event(const StringName& p_action,const InputEvent& p_event) {
void InputMap::action_erase_event(const StringName &p_action, const InputEvent &p_event) {
ERR_FAIL_COND( !input_map.has(p_action) );
ERR_FAIL_COND(!input_map.has(p_action));
List<InputEvent>::Element *E=_find_event(input_map[p_action].inputs,p_event);
List<InputEvent>::Element *E = _find_event(input_map[p_action].inputs, p_event);
if (E)
input_map[p_action].inputs.erase(E);
}
Array InputMap::_get_action_list(const StringName& p_action) {
Array InputMap::_get_action_list(const StringName &p_action) {
Array ret;
const List<InputEvent> *al = get_action_list(p_action);
if (al) {
for(const List<InputEvent>::Element *E=al->front();E;E=E->next()) {
for (const List<InputEvent>::Element *E = al->front(); E; E = E->next()) {
ret.push_back(E->get());;
ret.push_back(E->get());
}
}
return ret;
}
const List<InputEvent> *InputMap::get_action_list(const StringName& p_action) {
const List<InputEvent> *InputMap::get_action_list(const StringName &p_action) {
const Map<StringName, Action>::Element *E=input_map.find(p_action);
const Map<StringName, Action>::Element *E = input_map.find(p_action);
if (!E)
return NULL;
return &E->get().inputs;
}
bool InputMap::event_is_action(const InputEvent& p_event, const StringName& p_action) const {
bool InputMap::event_is_action(const InputEvent &p_event, const StringName &p_action) const {
Map<StringName,Action >::Element *E=input_map.find(p_action);
if(!E) {
ERR_EXPLAIN("Request for nonexistent InputMap action: "+String(p_action));
ERR_FAIL_COND_V(!E,false);
Map<StringName, Action>::Element *E = input_map.find(p_action);
if (!E) {
ERR_EXPLAIN("Request for nonexistent InputMap action: " + String(p_action));
ERR_FAIL_COND_V(!E, false);
}
if (p_event.type==InputEvent::ACTION) {
if (p_event.type == InputEvent::ACTION) {
return p_event.action.action==E->get().id;
return p_event.action.action == E->get().id;
}
return _find_event(E->get().inputs,p_event)!=NULL;
}
bool InputMap::event_is_joy_motion_action_pressed(const InputEvent& p_event) const {
ERR_FAIL_COND_V(p_event.type!=InputEvent::JOYSTICK_MOTION,false);
bool pressed=false;
//this could be optimized by having a separate list of joymotions?
for (Map<StringName, Action>::Element *A=input_map.front();A;A=A->next()) {
for (List<InputEvent>::Element *E=A->get().inputs.front();E;E=E->next()) {
const InputEvent& e=E->get();
if(e.type!=p_event.type)
continue;
if (e.type!=InputEvent::KEY && e.device!=p_event.device)
continue;
switch(p_event.type) {
case InputEvent::KEY: {
if (e.key.scancode==p_event.key.scancode && e.key.mod == p_event.key.mod)
return e.key.pressed;
} break;
case InputEvent::JOYSTICK_BUTTON: {
if (e.joy_button.button_index==p_event.joy_button.button_index) {
return e.joy_button.pressed;
}
} break;
case InputEvent::MOUSE_BUTTON: {
if (e.mouse_button.button_index==p_event.mouse_button.button_index) {
return e.mouse_button.pressed;
}
} break;
case InputEvent::JOYSTICK_MOTION: {
if (e.joy_motion.axis==p_event.joy_motion.axis) {
if (
(e.joy_motion.axis_value * p_event.joy_motion.axis_value >0) && //same axis
ABS(e.joy_motion.axis_value)>0.5 && ABS(p_event.joy_motion.axis_value)>0.5 )
pressed=true;
}
} break;
}
}
}
return pressed;
return _find_event(E->get().inputs, p_event) != NULL;
}
void InputMap::load_from_globals() {
input_map.clear();;
input_map.clear();
List<PropertyInfo> pinfo;
Globals::get_singleton()->get_property_list(&pinfo);
for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
const PropertyInfo &pi=E->get();
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
const PropertyInfo &pi = E->get();
if (!pi.name.begins_with("input/"))
continue;
String name = pi.name.substr(pi.name.find("/")+1,pi.name.length());
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
add_action(name);
Array va = Globals::get_singleton()->get(pi.name);;
Array va = Globals::get_singleton()->get(pi.name);
for(int i=0;i<va.size();i++) {
for (int i = 0; i < va.size(); i++) {
InputEvent ie=va[i];
if (ie.type==InputEvent::NONE)
InputEvent ie = va[i];
if (ie.type == InputEvent::NONE)
continue;
action_add_event(name,ie);
action_add_event(name, ie);
}
}
}
void InputMap::load_default() {
InputEvent key;
key.type=InputEvent::KEY;
key.type = InputEvent::KEY;
add_action("ui_accept");
key.key.scancode=KEY_RETURN;
action_add_event("ui_accept",key);
key.key.scancode=KEY_ENTER;
action_add_event("ui_accept",key);
key.key.scancode=KEY_SPACE;
action_add_event("ui_accept",key);
key.key.scancode = KEY_RETURN;
action_add_event("ui_accept", key);
key.key.scancode = KEY_ENTER;
action_add_event("ui_accept", key);
key.key.scancode = KEY_SPACE;
action_add_event("ui_accept", key);
add_action("ui_select");
key.key.scancode=KEY_SPACE;
action_add_event("ui_select",key);
key.key.scancode = KEY_SPACE;
action_add_event("ui_select", key);
add_action("ui_cancel");
key.key.scancode=KEY_ESCAPE;
action_add_event("ui_cancel",key);
key.key.scancode = KEY_ESCAPE;
action_add_event("ui_cancel", key);
add_action("ui_focus_next");
key.key.scancode=KEY_TAB;
action_add_event("ui_focus_next",key);
key.key.scancode = KEY_TAB;
action_add_event("ui_focus_next", key);
add_action("ui_focus_prev");
key.key.scancode=KEY_TAB;
key.key.mod.shift=true;
action_add_event("ui_focus_prev",key);
key.key.mod.shift=false;
key.key.scancode = KEY_TAB;
key.key.mod.shift = true;
action_add_event("ui_focus_prev", key);
key.key.mod.shift = false;
add_action("ui_left");
key.key.scancode=KEY_LEFT;
action_add_event("ui_left",key);
key.key.scancode = KEY_LEFT;
action_add_event("ui_left", key);
add_action("ui_right");
key.key.scancode=KEY_RIGHT;
action_add_event("ui_right",key);
key.key.scancode = KEY_RIGHT;
action_add_event("ui_right", key);
add_action("ui_up");
key.key.scancode=KEY_UP;
action_add_event("ui_up",key);
key.key.scancode = KEY_UP;
action_add_event("ui_up", key);
add_action("ui_down");
key.key.scancode=KEY_DOWN;
action_add_event("ui_down",key);
key.key.scancode = KEY_DOWN;
action_add_event("ui_down", key);
add_action("ui_page_up");
key.key.scancode=KEY_PAGEUP;
action_add_event("ui_page_up",key);
key.key.scancode = KEY_PAGEUP;
action_add_event("ui_page_up", key);
add_action("ui_page_down");
key.key.scancode=KEY_PAGEDOWN;
action_add_event("ui_page_down",key);
// set("display/orientation", "landscape");
key.key.scancode = KEY_PAGEDOWN;
action_add_event("ui_page_down", key);
// set("display/orientation", "landscape");
}
InputMap::InputMap() {
ERR_FAIL_COND(singleton);
singleton=this;
singleton = this;
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,12 +30,11 @@
#ifndef INPUT_MAP_H
#define INPUT_MAP_H
#include "object.h"
class InputMap : public Object {
OBJ_TYPE( InputMap, Object );
OBJ_TYPE(InputMap, Object);
static InputMap *singleton;
struct Action {
@@ -42,36 +42,32 @@ class InputMap : public Object {
List<InputEvent> inputs;
};
mutable Map<StringName, Action> input_map;
mutable Map<int,StringName> input_id_map;
mutable Map<int, StringName> input_id_map;
List<InputEvent>::Element *_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const;
List<InputEvent>::Element *_find_event(List<InputEvent> &p_list, const InputEvent &p_event) const;
Array _get_action_list(const StringName& p_action);
Array _get_action_list(const StringName &p_action);
Array _get_actions();
protected:
static void _bind_methods();
public:
public:
static _FORCE_INLINE_ InputMap *get_singleton() { return singleton; }
bool has_action(const StringName& p_action) const;
int get_action_id(const StringName& p_action) const;
bool has_action(const StringName &p_action) const;
int get_action_id(const StringName &p_action) const;
StringName get_action_from_id(int p_id) const;
List<StringName> get_actions() const;
void add_action(const StringName& p_action);
void erase_action(const StringName& p_action);
void add_action(const StringName &p_action);
void erase_action(const StringName &p_action);
void action_add_event(const StringName& p_action,const InputEvent& p_event);
bool action_has_event(const StringName& p_action,const InputEvent& p_event);
void action_erase_event(const StringName& p_action,const InputEvent& p_event);
const List<InputEvent> *get_action_list(const StringName& p_action);
bool event_is_action(const InputEvent& p_event, const StringName& p_action) const;
bool event_is_joy_motion_action_pressed(const InputEvent& p_event) const;
void action_add_event(const StringName &p_action, const InputEvent &p_event);
bool action_has_event(const StringName &p_action, const InputEvent &p_event);
void action_erase_event(const StringName &p_action, const InputEvent &p_event);
const List<InputEvent> *get_action_list(const StringName &p_action);
bool event_is_action(const InputEvent &p_event, const StringName &p_action) const;
void load_from_globals();
void load_default();

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,25 +30,25 @@
#ifdef _MSC_VER
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#ifdef NO_STDINT_H
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
#else
#include <stdint.h>

View File

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

View File

@@ -44,8 +44,7 @@ static uint8_t rj_sbox_inv(uint8_t);
#ifdef BACK_TO_TABLES
static const uint8_t sbox[256] =
{
static const uint8_t sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
@@ -79,8 +78,7 @@ static const uint8_t sbox[256] =
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
static const uint8_t sboxinv[256] =
{
static const uint8_t sboxinv[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -26,25 +27,25 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "zlib.h"
#include "os/copymem.h"
#include "compression.h"
#include "os/copymem.h"
#include "zlib.h"
#include "fastlz.h"
#include "zip_io.h"
int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,Mode p_mode) {
int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) {
switch(p_mode) {
switch (p_mode) {
case MODE_FASTLZ: {
if (p_src_size<16) {
if (p_src_size < 16) {
uint8_t src[16];
zeromem(&src[p_src_size],16-p_src_size);
copymem(src,p_src,p_src_size);
return fastlz_compress(src,16,p_dst);
zeromem(&src[p_src_size], 16 - p_src_size);
copymem(src, p_src, p_src_size);
return fastlz_compress(src, 16, p_dst);
} else {
return fastlz_compress(p_src,p_src_size,p_dst);
return fastlz_compress(p_src, p_src_size, p_dst);
}
} break;
@@ -54,16 +55,16 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,M
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
int err = deflateInit(&strm,Z_DEFAULT_COMPRESSION);
if (err!=Z_OK)
return -1;
int err = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
if (err != Z_OK)
return -1;
strm.avail_in=p_src_size;
int aout = deflateBound(&strm,p_src_size);;
strm.avail_out=aout;
strm.next_in=(Bytef*)p_src;
strm.next_out=p_dst;
deflate(&strm,Z_FINISH);
strm.avail_in = p_src_size;
int aout = deflateBound(&strm, p_src_size);
strm.avail_out = aout;
strm.next_in = (Bytef *)p_src;
strm.next_out = p_dst;
deflate(&strm, Z_FINISH);
aout = aout - strm.avail_out;
deflateEnd(&strm);
return aout;
@@ -74,15 +75,14 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,M
ERR_FAIL_V(-1);
}
int Compression::get_max_compressed_buffer_size(int p_src_size,Mode p_mode){
int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
switch(p_mode) {
switch (p_mode) {
case MODE_FASTLZ: {
int ss = p_src_size+p_src_size*6/100;
if (ss<66)
ss=66;
int ss = p_src_size + p_src_size * 6 / 100;
if (ss < 66)
ss = 66;
return ss;
} break;
@@ -92,32 +92,29 @@ int Compression::get_max_compressed_buffer_size(int p_src_size,Mode p_mode){
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
int err = deflateInit(&strm,Z_DEFAULT_COMPRESSION);
if (err!=Z_OK)
return -1;
int aout = deflateBound(&strm,p_src_size);
int err = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
if (err != Z_OK)
return -1;
int aout = deflateBound(&strm, p_src_size);
deflateEnd(&strm);
return aout;
} break;
}
ERR_FAIL_V(-1);
}
void Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode) {
void Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size,Mode p_mode){
switch(p_mode) {
switch (p_mode) {
case MODE_FASTLZ: {
if (p_dst_max_size<16) {
if (p_dst_max_size < 16) {
uint8_t dst[16];
fastlz_decompress(p_src,p_src_size,dst,16);
copymem(p_dst,dst,p_dst_max_size);
fastlz_decompress(p_src, p_src_size, dst, 16);
copymem(p_dst, dst, p_dst_max_size);
} else {
fastlz_decompress(p_src,p_src_size,p_dst,p_dst_max_size);
fastlz_decompress(p_src, p_src_size, p_dst, p_dst_max_size);
}
return;
} break;
@@ -127,19 +124,19 @@ void Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
strm.avail_in= 0;
strm.next_in=Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
int err = inflateInit(&strm);
ERR_FAIL_COND(err!=Z_OK);
ERR_FAIL_COND(err != Z_OK);
strm.avail_in=p_src_size;
strm.avail_out=p_dst_max_size;
strm.next_in=(Bytef*)p_src;
strm.next_out=p_dst;
strm.avail_in = p_src_size;
strm.avail_out = p_dst_max_size;
strm.next_in = (Bytef *)p_src;
strm.next_out = p_dst;
err = inflate(&strm,Z_FINISH);
err = inflate(&strm, Z_FINISH);
inflateEnd(&strm);
ERR_FAIL_COND(err!=Z_STREAM_END);
ERR_FAIL_COND(err != Z_STREAM_END);
return;
} break;
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,23 +32,18 @@
#include "typedefs.h"
class Compression
{
class Compression {
public:
enum Mode {
MODE_FASTLZ,
MODE_DEFLATE
};
static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,Mode p_mode=MODE_FASTLZ);
static int get_max_compressed_buffer_size(int p_src_size,Mode p_mode=MODE_FASTLZ);
static void decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size,Mode p_mode=MODE_FASTLZ);
static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_FASTLZ);
static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_FASTLZ);
static void decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_FASTLZ);
Compression();
};
#endif // COMPRESSION_H

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -27,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "config_file.h"
#include "os/keyboard.h"
#include "os/file_access.h"
#include "os/keyboard.h"
#include "variant_parser.h"
StringArray ConfigFile::_get_sections() const {
@@ -37,35 +38,33 @@ StringArray ConfigFile::_get_sections() const {
get_sections(&s);
StringArray arr;
arr.resize(s.size());
int idx=0;
for(const List<String>::Element *E=s.front();E;E=E->next()) {
int idx = 0;
for (const List<String>::Element *E = s.front(); E; E = E->next()) {
arr.set(idx++,E->get());
arr.set(idx++, E->get());
}
return arr;
}
StringArray ConfigFile::_get_section_keys(const String& p_section) const{
StringArray ConfigFile::_get_section_keys(const String &p_section) const {
List<String> s;
get_section_keys(p_section,&s);
get_section_keys(p_section, &s);
StringArray arr;
arr.resize(s.size());
int idx=0;
for(const List<String>::Element *E=s.front();E;E=E->next()) {
int idx = 0;
for (const List<String>::Element *E = s.front(); E; E = E->next()) {
arr.set(idx++,E->get());
arr.set(idx++, E->get());
}
return arr;
}
void ConfigFile::set_value(const String &p_section, const String &p_key, const Variant &p_value) {
void ConfigFile::set_value(const String& p_section, const String& p_key, const Variant& p_value){
if (p_value.get_type()==Variant::NIL) {
if (p_value.get_type() == Variant::NIL) {
//erase
if (!values.has(p_section))
return; // ?
@@ -76,55 +75,54 @@ void ConfigFile::set_value(const String& p_section, const String& p_key, const V
} else {
if (!values.has(p_section)) {
values[p_section]=Map<String, Variant>();
values[p_section] = Map<String, Variant>();
}
values[p_section][p_key]=p_value;
values[p_section][p_key] = p_value;
}
}
Variant ConfigFile::get_value(const String& p_section, const String& p_key, Variant p_default) const {
Variant ConfigFile::get_value(const String &p_section, const String &p_key, Variant p_default) const {
ERR_FAIL_COND_V(!values.has(p_section),p_default);
ERR_FAIL_COND_V(!values[p_section].has(p_key),p_default);
if (!values.has(p_section) || !values[p_section].has(p_key)) {
if (p_default.get_type() == Variant::NIL) {
ERR_EXPLAIN("Couldn't find the given section/key and no default was given");
ERR_FAIL_V(p_default);
}
return p_default;
}
return values[p_section][p_key];
}
bool ConfigFile::has_section(const String& p_section) const {
bool ConfigFile::has_section(const String &p_section) const {
return values.has(p_section);
}
bool ConfigFile::has_section_key(const String& p_section,const String& p_key) const {
bool ConfigFile::has_section_key(const String &p_section, const String &p_key) const {
if (!values.has(p_section))
return false;
return values[p_section].has(p_key);
}
void ConfigFile::get_sections(List<String> *r_sections) const{
void ConfigFile::get_sections(List<String> *r_sections) const {
for(const Map< String, Map<String, Variant> >::Element *E=values.front();E;E=E->next()) {
for (const Map<String, Map<String, Variant> >::Element *E = values.front(); E; E = E->next()) {
r_sections->push_back(E->key());
}
}
void ConfigFile::get_section_keys(const String& p_section,List<String> *r_keys) const{
void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys) const {
ERR_FAIL_COND(!values.has(p_section));
for(const Map<String, Variant> ::Element *E=values[p_section].front();E;E=E->next()) {
for (const Map<String, Variant>::Element *E = values[p_section].front(); E; E = E->next()) {
r_keys->push_back(E->key());
}
}
Error ConfigFile::save(const String& p_path){
Error ConfigFile::save(const String &p_path) {
Error err;
FileAccess *file = FileAccess::open(p_path,FileAccess::WRITE,&err);
FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err) {
if (file)
@@ -132,18 +130,17 @@ Error ConfigFile::save(const String& p_path){
return err;
}
for (Map<String, Map<String, Variant> >::Element *E = values.front(); E; E = E->next()) {
for(Map< String, Map<String, Variant> >::Element *E=values.front();E;E=E->next()) {
if (E!=values.front())
if (E != values.front())
file->store_string("\n");
file->store_string("["+E->key()+"]\n\n");
file->store_string("[" + E->key() + "]\n\n");
for(Map<String, Variant>::Element *F=E->get().front();F;F=F->next()) {
for (Map<String, Variant>::Element *F = E->get().front(); F; F = F->next()) {
String vstr;
VariantWriter::write_to_string(F->get(),vstr);
file->store_string(F->key()+"="+vstr+"\n");
VariantWriter::write_to_string(F->get(), vstr);
file->store_string(F->key() + "=" + vstr + "\n");
}
}
@@ -152,48 +149,46 @@ Error ConfigFile::save(const String& p_path){
return OK;
}
Error ConfigFile::load(const String& p_path) {
Error ConfigFile::load(const String &p_path) {
Error err;
FileAccess *f= FileAccess::open(p_path,FileAccess::READ,&err);
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (!f)
return ERR_CANT_OPEN;
VariantParser::StreamFile stream;
stream.f=f;
stream.f = f;
String assign;
Variant value;
VariantParser::Tag next_tag;
int lines=0;
int lines = 0;
String error_text;
String section;
while(true) {
while (true) {
assign=Variant();
assign = Variant();
next_tag.fields.clear();
next_tag.name=String();
next_tag.name = String();
err = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,NULL,true);
if (err==ERR_FILE_EOF) {
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true);
if (err == ERR_FILE_EOF) {
memdelete(f);
return OK;
}
else if (err!=OK) {
ERR_PRINTS("ConfgFile::load - "+p_path+":"+itos(lines)+" error: "+error_text);
} else if (err != OK) {
ERR_PRINTS("ConfgFile::load - " + p_path + ":" + itos(lines) + " error: " + error_text);
memdelete(f);
return err;
}
if (assign!=String()) {
set_value(section,assign,value);
} else if (next_tag.name!=String()) {
section=next_tag.name;
if (assign != String()) {
set_value(section, assign, value);
} else if (next_tag.name != String()) {
section = next_tag.name;
}
}
@@ -202,25 +197,20 @@ Error ConfigFile::load(const String& p_path) {
return OK;
}
void ConfigFile::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_value", "section", "key", "value"), &ConfigFile::set_value);
ObjectTypeDB::bind_method(_MD("get_value:Variant", "section", "key", "default"), &ConfigFile::get_value, DEFVAL(Variant()));
void ConfigFile::_bind_methods(){
ObjectTypeDB::bind_method(_MD("has_section", "section"), &ConfigFile::has_section);
ObjectTypeDB::bind_method(_MD("has_section_key", "section", "key"), &ConfigFile::has_section_key);
ObjectTypeDB::bind_method(_MD("set_value","section","key","value"),&ConfigFile::set_value);
ObjectTypeDB::bind_method(_MD("get_value:Variant","section","key","default"),&ConfigFile::get_value,DEFVAL(Variant()));
ObjectTypeDB::bind_method(_MD("has_section","section"),&ConfigFile::has_section);
ObjectTypeDB::bind_method(_MD("has_section_key","section","key"),&ConfigFile::has_section_key);
ObjectTypeDB::bind_method(_MD("get_sections"),&ConfigFile::_get_sections);
ObjectTypeDB::bind_method(_MD("get_section_keys","section"),&ConfigFile::_get_section_keys);
ObjectTypeDB::bind_method(_MD("load:Error","path"),&ConfigFile::load);
ObjectTypeDB::bind_method(_MD("save:Error","path"),&ConfigFile::save);
ObjectTypeDB::bind_method(_MD("get_sections"), &ConfigFile::_get_sections);
ObjectTypeDB::bind_method(_MD("get_section_keys", "section"), &ConfigFile::_get_section_keys);
ObjectTypeDB::bind_method(_MD("load:Error", "path"), &ConfigFile::load);
ObjectTypeDB::bind_method(_MD("save:Error", "path"), &ConfigFile::save);
}
ConfigFile::ConfigFile()
{
ConfigFile::ConfigFile() {
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,31 +32,30 @@
#include "reference.h"
class ConfigFile : public Reference {
OBJ_TYPE(ConfigFile,Reference);
OBJ_TYPE(ConfigFile, Reference);
Map< String, Map<String, Variant> > values;
Map<String, Map<String, Variant> > values;
StringArray _get_sections() const;
StringArray _get_section_keys(const String& p_section) const;
StringArray _get_section_keys(const String &p_section) const;
protected:
static void _bind_methods();
public:
void set_value(const String &p_section, const String &p_key, const Variant &p_value);
Variant get_value(const String &p_section, const String &p_key, Variant p_default = Variant()) const;
void set_value(const String& p_section, const String& p_key, const Variant& p_value);
Variant get_value(const String& p_section, const String& p_key, Variant p_default=Variant()) const;
bool has_section(const String& p_section) const;
bool has_section_key(const String& p_section,const String& p_key) const;
bool has_section(const String &p_section) const;
bool has_section_key(const String &p_section, const String &p_key) const;
void get_sections(List<String> *r_sections) const;
void get_section_keys(const String& p_section,List<String> *r_keys) const;
void get_section_keys(const String &p_section, List<String> *r_keys) const;
Error save(const String& p_path);
Error load(const String& p_path);
Error save(const String &p_path);
Error load(const String &p_path);
ConfigFile();
};

1
core/io/export_data.cpp Normal file
View File

@@ -0,0 +1 @@
#include "export_data.h"

84
core/io/export_data.h Normal file
View File

@@ -0,0 +1,84 @@
#ifndef EXPORT_DATA_H
#define EXPORT_DATA_H
#include "map.h"
#include "variant.h"
#include "vector.h"
struct ExportData {
struct Dependency {
String path;
String type;
};
Map<int, Dependency> dependencies;
struct PropertyData {
String name;
Variant value;
};
struct ResourceData {
String type;
int index;
List<PropertyData> properties;
};
Vector<ResourceData> resources;
struct NodeData {
bool text_data;
bool instanced;
String name;
String type;
String instance;
//int info
int owner_int; //depending type
int parent_int;
bool instance_is_placeholder;
//text info
NodePath parent;
NodePath owner;
String instance_placeholder;
Vector<String> groups;
List<PropertyData> properties;
NodeData() {
parent_int = 0;
owner_int = 0;
text_data = true;
instanced = false;
}
};
Vector<NodeData> nodes;
struct Connection {
bool text_data;
int from_int;
int to_int;
NodePath from;
NodePath to;
String signal;
String method;
Array binds;
int flags;
Connection() { text_data = true; }
};
Vector<Connection> connections;
Vector<NodePath> editables;
Array node_paths; //for integer packed data
Variant base_scene;
};
#endif // EXPORT_DATA_H

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -92,7 +93,7 @@ bool FileAccessBuffered::eof_reached() const {
uint8_t FileAccessBuffered::get_8() const {
ERR_FAIL_COND_V(!file.open,0);
ERR_FAIL_COND_V(!file.open, 0);
uint8_t byte = 0;
if (cache_data_left() >= 1) {
@@ -105,7 +106,7 @@ uint8_t FileAccessBuffered::get_8() const {
return byte;
};
int FileAccessBuffered::get_buffer(uint8_t *p_dest,int p_elements) const {
int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_elements) const {
ERR_FAIL_COND_V(!file.open, -1);
@@ -135,7 +136,6 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest,int p_elements) const {
return total_read;
};
int to_read = p_elements;
int total_read = 0;
while (to_read > 0) {
@@ -154,7 +154,7 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest,int p_elements) const {
int r = MIN(left, to_read);
//DVector<uint8_t>::Read read = cache.buffer.read();
//memcpy(p_dest+total_read, &read.ptr()[file.offset - cache.offset], r);
memcpy(p_dest+total_read, cache.buffer.ptr() + (file.offset - cache.offset), r);
memcpy(p_dest + total_read, cache.buffer.ptr() + (file.offset - cache.offset), r);
file.offset += r;
total_read += r;
@@ -179,6 +179,5 @@ FileAccessBuffered::FileAccessBuffered() {
cache_size = DEFAULT_CACHE_SIZE;
};
FileAccessBuffered::~FileAccessBuffered(){
FileAccessBuffered::~FileAccessBuffered() {
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -42,14 +43,12 @@ public:
};
private:
int cache_size;
int cache_data_left() const;
mutable Error last_error;
protected:
Error set_error(Error p_error) const;
mutable struct File {
@@ -67,23 +66,22 @@ protected:
int offset;
} cache;
virtual int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const =0;
virtual int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const = 0;
void set_cache_size(int p_size);
int get_cache_size();
public:
virtual size_t get_pos() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual bool eof_reached() const;
virtual uint8_t get_8() const;
virtual int get_buffer(uint8_t *p_dst,int p_length) const; ///< get an array of bytes
virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes
virtual bool is_open() const;
@@ -94,4 +92,3 @@ public:
};
#endif

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,16 +32,16 @@
#include "core/io/file_access_buffered.h"
template<class T>
template <class T>
class FileAccessBufferedFA : public FileAccessBuffered {
T f;
int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const {
ERR_FAIL_COND_V( !f.is_open(), -1 );
ERR_FAIL_COND_V(!f.is_open(), -1);
((T*)&f)->seek(p_offset);
((T *)&f)->seek(p_offset);
if (p_dest) {
@@ -63,9 +64,9 @@ class FileAccessBufferedFA : public FileAccessBuffered {
};
};
static FileAccess* create() {
static FileAccess *create() {
return memnew( FileAccessBufferedFA<T>() );
return memnew(FileAccessBufferedFA<T>());
};
protected:
@@ -75,29 +76,27 @@ protected:
};
public:
void store_8(uint8_t p_dest) {
f.store_8(p_dest);
};
void store_buffer(const uint8_t *p_src,int p_length) {
void store_buffer(const uint8_t *p_src, int p_length) {
f.store_buffer(p_src, p_length);
};
bool file_exists(const String& p_name) {
bool file_exists(const String &p_name) {
return f.file_exists(p_name);
};
Error _open(const String& p_path, int p_mode_flags) {
Error _open(const String &p_path, int p_mode_flags) {
close();
Error ret = f._open(p_path, p_mode_flags);
if (ret !=OK)
if (ret != OK)
return ret;
//ERR_FAIL_COND_V( ret != OK, ret );
@@ -127,21 +126,19 @@ public:
set_error(OK);
};
// static void make_default() {
// static void make_default() {
//FileAccess::create_func = FileAccessBufferedFA<T>::create;
// };
//FileAccess::create_func = FileAccessBufferedFA<T>::create;
// };
virtual uint64_t _get_modified_time(const String& p_file) {
virtual uint64_t _get_modified_time(const String &p_file) {
return f._get_modified_time(p_file);
}
FileAccessBufferedFA() {
FileAccessBufferedFA(){
};
};
#endif // FILE_ACCESS_BUFFERED_FA_H

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -28,244 +29,223 @@
/*************************************************************************/
#include "file_access_compressed.h"
#include "print_string.h"
void FileAccessCompressed::configure(const String& p_magic, Compression::Mode p_mode, int p_block_size) {
void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, int p_block_size) {
magic=p_magic.ascii().get_data();
if (magic.length()>4)
magic=magic.substr(0,4);
magic = p_magic.ascii().get_data();
if (magic.length() > 4)
magic = magic.substr(0, 4);
else {
while(magic.length()<4)
magic+=" ";
while (magic.length() < 4)
magic += " ";
}
cmode=p_mode;
block_size=p_block_size;
}
#define WRITE_FIT(m_bytes) \
{\
if (write_pos+(m_bytes) > write_max) {\
write_max=write_pos+(m_bytes);\
}\
if (write_max > write_buffer_size) {\
write_buffer_size = nearest_power_of_2( write_max );\
buffer.resize(write_buffer_size);\
write_ptr=buffer.ptr();\
}\
cmode = p_mode;
block_size = p_block_size;
}
#define WRITE_FIT(m_bytes) \
{ \
if (write_pos + (m_bytes) > write_max) { \
write_max = write_pos + (m_bytes); \
} \
if (write_max > write_buffer_size) { \
write_buffer_size = nearest_power_of_2(write_max); \
buffer.resize(write_buffer_size); \
write_ptr = buffer.ptr(); \
} \
}
Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
f=p_base;
cmode=(Compression::Mode)f->get_32();
block_size=f->get_32();
read_total=f->get_32();
int bc = (read_total/block_size)+1;
int acc_ofs=f->get_pos()+bc*4;
int max_bs=0;
for(int i=0;i<bc;i++) {
f = p_base;
cmode = (Compression::Mode)f->get_32();
block_size = f->get_32();
read_total = f->get_32();
int bc = (read_total / block_size) + 1;
int acc_ofs = f->get_pos() + bc * 4;
int max_bs = 0;
for (int i = 0; i < bc; i++) {
ReadBlock rb;
rb.offset=acc_ofs;
rb.csize=f->get_32();
acc_ofs+=rb.csize;
max_bs=MAX(max_bs,rb.csize);
rb.offset = acc_ofs;
rb.csize = f->get_32();
acc_ofs += rb.csize;
max_bs = MAX(max_bs, rb.csize);
read_blocks.push_back(rb);
}
comp_buffer.resize(max_bs);
buffer.resize(block_size);
read_ptr=buffer.ptr();
f->get_buffer(comp_buffer.ptr(),read_blocks[0].csize);
at_end=false;
read_eof=false;
read_block_count=bc;
read_block_size=read_blocks.size()==1?read_total:block_size;
read_ptr = buffer.ptr();
f->get_buffer(comp_buffer.ptr(), read_blocks[0].csize);
at_end = false;
read_eof = false;
read_block_count = bc;
read_block_size = read_blocks.size() == 1 ? read_total : block_size;
Compression::decompress(buffer.ptr(),read_block_size,comp_buffer.ptr(),read_blocks[0].csize,cmode);
read_block=0;
read_pos=0;
Compression::decompress(buffer.ptr(), read_block_size, comp_buffer.ptr(), read_blocks[0].csize, cmode);
read_block = 0;
read_pos = 0;
return OK;
}
Error FileAccessCompressed::_open(const String& p_path, int p_mode_flags){
Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V(p_mode_flags==READ_WRITE,ERR_UNAVAILABLE);
ERR_FAIL_COND_V(p_mode_flags == READ_WRITE, ERR_UNAVAILABLE);
if (f)
close();
Error err;
f = FileAccess::open(p_path,p_mode_flags,&err);
if (err!=OK) {
f = FileAccess::open(p_path, p_mode_flags, &err);
if (err != OK) {
//not openable
f=NULL;
f = NULL;
return err;
}
if (p_mode_flags&WRITE) {
if (p_mode_flags & WRITE) {
buffer.clear();
writing=true;
write_pos=0;
write_buffer_size=256;
writing = true;
write_pos = 0;
write_buffer_size = 256;
buffer.resize(256);
write_max=0;
write_ptr=buffer.ptr();
write_max = 0;
write_ptr = buffer.ptr();
//don't store anything else unless it's done saving!
} else {
char rmagic[5];
f->get_buffer((uint8_t*)rmagic,4);
rmagic[4]=0;
if (magic!=rmagic) {
f->get_buffer((uint8_t *)rmagic, 4);
rmagic[4] = 0;
if (magic != rmagic) {
memdelete(f);
f=NULL;
f = NULL;
return ERR_FILE_UNRECOGNIZED;
}
open_after_magic(f);
}
return OK;
}
void FileAccessCompressed::close(){
void FileAccessCompressed::close() {
if (!f)
return;
if (writing) {
//save block table and all compressed blocks
CharString mgc = magic.utf8();
f->store_buffer((const uint8_t*)mgc.get_data(),mgc.length()); //write header 4
f->store_buffer((const uint8_t *)mgc.get_data(), mgc.length()); //write header 4
f->store_32(cmode); //write compression mode 4
f->store_32(block_size); //write block size 4
f->store_32(write_max); //max amount of data written 4
int bc=(write_max/block_size)+1;
int bc = (write_max / block_size) + 1;
for(int i=0;i<bc;i++) {
for (int i = 0; i < bc; i++) {
f->store_32(0); //compressed sizes, will update later
}
Vector<int> block_sizes;
for(int i=0;i<bc;i++) {
for (int i = 0; i < bc; i++) {
int bl = i==(bc-1) ? write_max % block_size : block_size;
uint8_t *bp = &write_ptr[i*block_size];
int bl = i == (bc - 1) ? write_max % block_size : block_size;
uint8_t *bp = &write_ptr[i * block_size];
Vector<uint8_t> cblock;
cblock.resize(Compression::get_max_compressed_buffer_size(bl,cmode));
int s = Compression::compress(cblock.ptr(),bp,bl,cmode);
cblock.resize(Compression::get_max_compressed_buffer_size(bl, cmode));
int s = Compression::compress(cblock.ptr(), bp, bl, cmode);
f->store_buffer(cblock.ptr(),s);
f->store_buffer(cblock.ptr(), s);
block_sizes.push_back(s);
}
f->seek(16); //ok write block sizes
for(int i=0;i<bc;i++)
for (int i = 0; i < bc; i++)
f->store_32(block_sizes[i]);
f->seek_end();
f->store_buffer((const uint8_t*)mgc.get_data(),mgc.length()); //magic at the end too
f->store_buffer((const uint8_t *)mgc.get_data(), mgc.length()); //magic at the end too
buffer.clear();
} else {
comp_buffer.clear();
buffer.clear();
read_blocks.clear();
}
memdelete(f);
f=NULL;
f = NULL;
}
bool FileAccessCompressed::is_open() const{
bool FileAccessCompressed::is_open() const {
return f!=NULL;
return f != NULL;
}
void FileAccessCompressed::seek(size_t p_position){
void FileAccessCompressed::seek(size_t p_position) {
ERR_FAIL_COND(!f);
if (writing) {
ERR_FAIL_COND(p_position>write_max);
ERR_FAIL_COND(p_position > write_max);
write_pos=p_position;
write_pos = p_position;
} else {
ERR_FAIL_COND(p_position>read_total);
if (p_position==read_total) {
at_end=true;
ERR_FAIL_COND(p_position > read_total);
if (p_position == read_total) {
at_end = true;
} else {
int block_idx = p_position/block_size;
if (block_idx!=read_block) {
int block_idx = p_position / block_size;
if (block_idx != read_block) {
read_block=block_idx;
read_block = block_idx;
f->seek(read_blocks[read_block].offset);
f->get_buffer(comp_buffer.ptr(),read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(),read_blocks.size()==1?read_total:block_size,comp_buffer.ptr(),read_blocks[read_block].csize,cmode);
read_block_size=read_block==read_block_count-1?read_total%block_size:block_size;
f->get_buffer(comp_buffer.ptr(), read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode);
read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size;
}
read_pos=p_position%block_size;
read_pos = p_position % block_size;
}
}
}
void FileAccessCompressed::seek_end(int64_t p_position){
void FileAccessCompressed::seek_end(int64_t p_position) {
ERR_FAIL_COND(!f);
if (writing) {
seek(write_max+p_position);
seek(write_max + p_position);
} else {
seek(read_total+p_position);
seek(read_total + p_position);
}
}
size_t FileAccessCompressed::get_pos() const{
size_t FileAccessCompressed::get_pos() const {
ERR_FAIL_COND_V(!f,0);
ERR_FAIL_COND_V(!f, 0);
if (writing) {
return write_pos;
} else {
return read_block*block_size+read_pos;
return read_block * block_size + read_pos;
}
}
size_t FileAccessCompressed::get_len() const{
size_t FileAccessCompressed::get_len() const {
ERR_FAIL_COND_V(!f,0);
ERR_FAIL_COND_V(!f, 0);
if (writing) {
return write_max;
@@ -274,9 +254,9 @@ size_t FileAccessCompressed::get_len() const{
}
}
bool FileAccessCompressed::eof_reached() const{
bool FileAccessCompressed::eof_reached() const {
ERR_FAIL_COND_V(!f,false);
ERR_FAIL_COND_V(!f, false);
if (writing) {
return false;
} else {
@@ -284,106 +264,99 @@ bool FileAccessCompressed::eof_reached() const{
}
}
uint8_t FileAccessCompressed::get_8() const{
uint8_t FileAccessCompressed::get_8() const {
ERR_FAIL_COND_V(writing,0);
ERR_FAIL_COND_V(!f,0);
ERR_FAIL_COND_V(writing, 0);
ERR_FAIL_COND_V(!f, 0);
if (at_end) {
read_eof=true;
read_eof = true;
return 0;
}
uint8_t ret = read_ptr[read_pos];
read_pos++;
if (read_pos>=read_block_size) {
if (read_pos >= read_block_size) {
read_block++;
if (read_block<read_block_count) {
if (read_block < read_block_count) {
//read another block of compressed data
f->get_buffer(comp_buffer.ptr(),read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(),read_blocks.size()==1?read_total:block_size,comp_buffer.ptr(),read_blocks[read_block].csize,cmode);
read_block_size=read_block==read_block_count-1?read_total%block_size:block_size;
read_pos=0;
f->get_buffer(comp_buffer.ptr(), read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode);
read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size;
read_pos = 0;
} else {
read_block--;
at_end=true;
ret =0;
at_end = true;
ret = 0;
}
}
return ret;
}
int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const{
int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(writing,0);
ERR_FAIL_COND_V(!f,0);
ERR_FAIL_COND_V(writing, 0);
ERR_FAIL_COND_V(!f, 0);
if (at_end) {
read_eof=true;
read_eof = true;
return 0;
}
for (int i = 0; i < p_length; i++) {
for(int i=0;i<p_length;i++) {
p_dst[i]=read_ptr[read_pos];
p_dst[i] = read_ptr[read_pos];
read_pos++;
if (read_pos>=read_block_size) {
if (read_pos >= read_block_size) {
read_block++;
if (read_block<read_block_count) {
if (read_block < read_block_count) {
//read another block of compressed data
f->get_buffer(comp_buffer.ptr(),read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(),read_blocks.size()==1?read_total:block_size,comp_buffer.ptr(),read_blocks[read_block].csize,cmode);
read_block_size=read_block==read_block_count-1?read_total%block_size:block_size;
read_pos=0;
f->get_buffer(comp_buffer.ptr(), read_blocks[read_block].csize);
Compression::decompress(buffer.ptr(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode);
read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size;
read_pos = 0;
} else {
read_block--;
at_end=true;
if (i<p_length-1)
read_eof=true;
at_end = true;
if (i < p_length - 1)
read_eof = true;
return i;
}
}
}
return p_length;
}
Error FileAccessCompressed::get_error() const{
Error FileAccessCompressed::get_error() const {
return read_eof?ERR_FILE_EOF:OK;
return read_eof ? ERR_FILE_EOF : OK;
}
void FileAccessCompressed::store_8(uint8_t p_dest){
void FileAccessCompressed::store_8(uint8_t p_dest) {
ERR_FAIL_COND(!f);
ERR_FAIL_COND(!writing);
WRITE_FIT(1);
write_ptr[write_pos++]=p_dest;
write_ptr[write_pos++] = p_dest;
}
bool FileAccessCompressed::file_exists(const String& p_name){
bool FileAccessCompressed::file_exists(const String &p_name) {
FileAccess *fa = FileAccess::open(p_name,FileAccess::READ);
FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
if (!fa)
return false;
memdelete(fa);
return true;
}
uint64_t FileAccessCompressed::_get_modified_time(const String& p_file) {
uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
if (f)
return f->get_modified_time(p_file);
@@ -393,29 +366,27 @@ uint64_t FileAccessCompressed::_get_modified_time(const String& p_file) {
FileAccessCompressed::FileAccessCompressed() {
f=NULL;
magic="GCMP";
block_size=16384;
cmode=Compression::MODE_DEFLATE;
writing=false;
write_ptr=0;
write_buffer_size=0;
write_max=0;
block_size=0;
read_eof=false;
at_end=false;
read_total=0;
read_ptr=NULL;
read_block=0;
read_block_count=0;
read_block_size=0;
read_pos=0;
f = NULL;
magic = "GCMP";
block_size = 16384;
cmode = Compression::MODE_DEFLATE;
writing = false;
write_ptr = 0;
write_buffer_size = 0;
write_max = 0;
block_size = 0;
read_eof = false;
at_end = false;
read_total = 0;
read_ptr = NULL;
read_block = 0;
read_block_count = 0;
read_block_size = 0;
read_pos = 0;
}
FileAccessCompressed::~FileAccessCompressed(){
FileAccessCompressed::~FileAccessCompressed() {
if (f)
close();
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -37,7 +38,7 @@ class FileAccessCompressed : public FileAccess {
Compression::Mode cmode;
bool writing;
int write_pos;
uint8_t*write_ptr;
uint8_t *write_ptr;
int write_buffer_size;
int write_max;
int block_size;
@@ -58,24 +59,21 @@ class FileAccessCompressed : public FileAccess {
Vector<ReadBlock> read_blocks;
int read_total;
String magic;
mutable Vector<uint8_t> buffer;
FileAccess *f;
public:
void configure(const String& p_magic, Compression::Mode p_mode=Compression::MODE_FASTLZ, int p_block_size=4096);
public:
void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_FASTLZ, int p_block_size = 4096);
Error open_after_magic(FileAccess *p_base);
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual size_t get_pos() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
@@ -88,14 +86,12 @@ public:
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual bool file_exists(const String& p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String& p_file);
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file);
FileAccessCompressed();
virtual ~FileAccessCompressed();
};
#endif // FILE_ACCESS_COMPRESSED_H

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -36,55 +37,55 @@
#include "core/variant.h"
#include <stdio.h>
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base,const Vector<uint8_t>& p_key,Mode p_mode) {
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode) {
//print_line("open and parse!");
ERR_FAIL_COND_V(file!=NULL,ERR_ALREADY_IN_USE);
ERR_FAIL_COND_V(p_key.size()!=32,ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(file != NULL, ERR_ALREADY_IN_USE);
ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
pos=0;
eofed=false;
pos = 0;
eofed = false;
if (p_mode==MODE_WRITE_AES256) {
if (p_mode == MODE_WRITE_AES256) {
data.clear();
writing=true;
file=p_base;
mode=p_mode;
key=p_key;
writing = true;
file = p_base;
mode = p_mode;
key = p_key;
} else if (p_mode==MODE_READ) {
} else if (p_mode == MODE_READ) {
writing=false;
key=p_key;
writing = false;
key = p_key;
uint32_t magic = p_base->get_32();
print_line("MAGIC: "+itos(magic));
ERR_FAIL_COND_V(magic!=COMP_MAGIC,ERR_FILE_UNRECOGNIZED);
mode=Mode(p_base->get_32());
ERR_FAIL_INDEX_V(mode,MODE_MAX,ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(mode==0,ERR_FILE_CORRUPT);
print_line("MODE: "+itos(mode));
print_line("MAGIC: " + itos(magic));
ERR_FAIL_COND_V(magic != COMP_MAGIC, ERR_FILE_UNRECOGNIZED);
mode = Mode(p_base->get_32());
ERR_FAIL_INDEX_V(mode, MODE_MAX, ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(mode == 0, ERR_FILE_CORRUPT);
print_line("MODE: " + itos(mode));
unsigned char md5d[16];
p_base->get_buffer(md5d,16);
length=p_base->get_64();
base=p_base->get_pos();
ERR_FAIL_COND_V(p_base->get_len() < base+length, ERR_FILE_CORRUPT );
p_base->get_buffer(md5d, 16);
length = p_base->get_64();
base = p_base->get_pos();
ERR_FAIL_COND_V(p_base->get_len() < base + length, ERR_FILE_CORRUPT);
int ds = length;
if (ds % 16) {
ds+=16-(ds % 16);
ds += 16 - (ds % 16);
}
data.resize(ds);
int blen = p_base->get_buffer(data.ptr(),ds);
ERR_FAIL_COND_V(blen!=ds,ERR_FILE_CORRUPT);
int blen = p_base->get_buffer(data.ptr(), ds);
ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT);
aes256_context ctx;
aes256_init(&ctx,key.ptr());
aes256_init(&ctx, key.ptr());
for(size_t i=0;i<ds;i+=16) {
for (size_t i = 0; i < ds; i += 16) {
aes256_decrypt_ecb(&ctx,&data[i]);
aes256_decrypt_ecb(&ctx, &data[i]);
}
aes256_done(&ctx);
@@ -93,37 +94,32 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base,const Vector<uint8_
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5,data.ptr(),data.size());
MD5Update(&md5, data.ptr(), data.size());
MD5Final(&md5);
ERR_FAIL_COND_V(String::md5(md5.digest) != String::md5(md5d), ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(String::md5(md5.digest)!=String::md5(md5d),ERR_FILE_CORRUPT) ;
file=p_base;
file = p_base;
}
return OK;
}
Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base,const String& p_key,Mode p_mode){
Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode) {
String cs = p_key.md5_text();
ERR_FAIL_COND_V(cs.length()!=32,ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(cs.length() != 32, ERR_INVALID_PARAMETER);
Vector<uint8_t> key;
key.resize(32);
for(int i=0;i<32;i++) {
for (int i = 0; i < 32; i++) {
key[i]=cs[i];
key[i] = cs[i];
}
return open_and_parse(p_base,key,p_mode);
return open_and_parse(p_base, key, p_mode);
}
Error FileAccessEncrypted::_open(const String& p_path, int p_mode_flags) {
Error FileAccessEncrypted::_open(const String &p_path, int p_mode_flags) {
return OK;
}
@@ -137,26 +133,26 @@ void FileAccessEncrypted::close() {
Vector<uint8_t> compressed;
size_t len = data.size();
if (len % 16) {
len+=16-(len % 16);
len += 16 - (len % 16);
}
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5,data.ptr(),data.size());
MD5Update(&md5, data.ptr(), data.size());
MD5Final(&md5);
compressed.resize(len);
zeromem( compressed.ptr(), len );
for(int i=0;i<data.size();i++) {
compressed[i]=data[i];
zeromem(compressed.ptr(), len);
for (int i = 0; i < data.size(); i++) {
compressed[i] = data[i];
}
aes256_context ctx;
aes256_init(&ctx,key.ptr());
aes256_init(&ctx, key.ptr());
for(size_t i=0;i<len;i+=16) {
for (size_t i = 0; i < len; i += 16) {
aes256_encrypt_ecb(&ctx,&compressed[i]);
aes256_encrypt_ecb(&ctx, &compressed[i]);
}
aes256_done(&ctx);
@@ -164,14 +160,13 @@ void FileAccessEncrypted::close() {
file->store_32(COMP_MAGIC);
file->store_32(mode);
file->store_buffer(md5.digest,16);
file->store_buffer(md5.digest, 16);
file->store_64(data.size());
file->store_buffer(compressed.ptr(),compressed.size());
file->store_buffer(compressed.ptr(), compressed.size());
file->close();
memdelete(file);
file=NULL;
file = NULL;
data.clear();
} else {
@@ -179,143 +174,133 @@ void FileAccessEncrypted::close() {
file->close();
memdelete(file);
data.clear();
file=NULL;
file = NULL;
}
}
bool FileAccessEncrypted::is_open() const{
bool FileAccessEncrypted::is_open() const {
return file!=NULL;
return file != NULL;
}
void FileAccessEncrypted::seek(size_t p_position){
void FileAccessEncrypted::seek(size_t p_position) {
if (p_position > (size_t)data.size())
p_position=data.size();
pos=p_position;
eofed=false;
p_position = data.size();
pos = p_position;
eofed = false;
}
void FileAccessEncrypted::seek_end(int64_t p_position) {
void FileAccessEncrypted::seek_end(int64_t p_position){
seek( data.size() + p_position );
seek(data.size() + p_position);
}
size_t FileAccessEncrypted::get_pos() const{
size_t FileAccessEncrypted::get_pos() const {
return pos;
}
size_t FileAccessEncrypted::get_len() const{
size_t FileAccessEncrypted::get_len() const {
return data.size();
}
bool FileAccessEncrypted::eof_reached() const{
bool FileAccessEncrypted::eof_reached() const {
return eofed;
}
uint8_t FileAccessEncrypted::get_8() const{
uint8_t FileAccessEncrypted::get_8() const {
ERR_FAIL_COND_V(writing,0);
if (pos>=data.size()) {
eofed=true;
ERR_FAIL_COND_V(writing, 0);
if (pos >= data.size()) {
eofed = true;
return 0;
}
uint8_t b = data[pos];
pos++;
return b;
}
int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const{
int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(writing,0);
ERR_FAIL_COND_V(writing, 0);
int to_copy=MIN(p_length,data.size()-pos);
for(int i=0;i<to_copy;i++) {
int to_copy = MIN(p_length, data.size() - pos);
for (int i = 0; i < to_copy; i++) {
p_dst[i]=data[pos++];
p_dst[i] = data[pos++];
}
if (to_copy<p_length) {
eofed=true;
if (to_copy < p_length) {
eofed = true;
}
return to_copy;
}
Error FileAccessEncrypted::get_error() const{
Error FileAccessEncrypted::get_error() const {
return eofed?ERR_FILE_EOF:OK;
return eofed ? ERR_FILE_EOF : OK;
}
void FileAccessEncrypted::store_buffer(const uint8_t *p_src,int p_length) {
void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) {
ERR_FAIL_COND(!writing);
if (pos<data.size()) {
if (pos < data.size()) {
for(int i=0;i<p_length;i++) {
for (int i = 0; i < p_length; i++) {
store_8(p_src[i]);
}
} else if (pos==data.size()) {
} else if (pos == data.size()) {
data.resize(pos+p_length);
for(int i=0;i<p_length;i++) {
data.resize(pos + p_length);
for (int i = 0; i < p_length; i++) {
data[pos+i]=p_src[i];
data[pos + i] = p_src[i];
}
pos+=p_length;
pos += p_length;
}
}
void FileAccessEncrypted::store_8(uint8_t p_dest){
void FileAccessEncrypted::store_8(uint8_t p_dest) {
ERR_FAIL_COND(!writing);
if (pos<data.size()) {
data[pos]=p_dest;
if (pos < data.size()) {
data[pos] = p_dest;
pos++;
} else if (pos==data.size()){
} else if (pos == data.size()) {
data.push_back(p_dest);
pos++;
}
}
bool FileAccessEncrypted::file_exists(const String& p_name){
bool FileAccessEncrypted::file_exists(const String &p_name) {
FileAccess *fa = FileAccess::open(p_name,FileAccess::READ);
FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
if (!fa)
return false;
memdelete(fa);
return true;
}
uint64_t FileAccessEncrypted::_get_modified_time(const String& p_file){
uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
return 0;
}
FileAccessEncrypted::FileAccessEncrypted() {
file=NULL;
pos=0;
eofed=false;
mode=MODE_MAX;
writing=false;
file = NULL;
pos = 0;
eofed = false;
mode = MODE_MAX;
writing = false;
}
FileAccessEncrypted::~FileAccessEncrypted() {
if (file)

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,12 +30,10 @@
#ifndef FILE_ACCESS_ENCRYPTED_H
#define FILE_ACCESS_ENCRYPTED_H
#include "os/file_access.h"
class FileAccessEncrypted : public FileAccess {
public:
enum Mode {
MODE_READ,
MODE_WRITE_AES256,
@@ -42,8 +41,6 @@ public:
};
private:
Mode mode;
Vector<uint8_t> key;
bool writing;
@@ -54,21 +51,16 @@ private:
mutable size_t pos;
mutable bool eofed;
public:
Error open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode);
Error open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode);
Error open_and_parse(FileAccess *p_base,const Vector<uint8_t>& p_key,Mode p_mode);
Error open_and_parse_password(FileAccess *p_base,const String& p_key,Mode p_mode);
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual size_t get_pos() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
@@ -80,11 +72,11 @@ public:
virtual Error get_error() const; ///< get last error
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual void store_buffer(const uint8_t *p_src,int p_length); ///< store an array of bytes
virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes
virtual bool file_exists(const String& p_name); ///< return true if a file exists
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String& p_file);
virtual uint64_t _get_modified_time(const String &p_file);
FileAccessEncrypted();
~FileAccessEncrypted();

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -28,12 +29,12 @@
/*************************************************************************/
#include "file_access_memory.h"
#include "os/dir_access.h"
#include "os/copymem.h"
#include "globals.h"
#include "map.h"
#include "os/copymem.h"
#include "os/dir_access.h"
static Map<String, Vector<uint8_t> >* files = NULL;
static Map<String, Vector<uint8_t> > *files = NULL;
void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) {
@@ -59,37 +60,35 @@ void FileAccessMemory::cleanup() {
memdelete(files);
}
FileAccess* FileAccessMemory::create() {
FileAccess *FileAccessMemory::create() {
return memnew(FileAccessMemory);
}
bool FileAccessMemory::file_exists(const String& p_name) {
bool FileAccessMemory::file_exists(const String &p_name) {
String name = fix_path(p_name);
// name = DirAccess::normalize_path(name);
// name = DirAccess::normalize_path(name);
return files && (files->find(name) != NULL);
}
Error FileAccessMemory::open_custom(const uint8_t *p_data, int p_len) {
Error FileAccessMemory::open_custom(const uint8_t* p_data, int p_len) {
data=(uint8_t*)p_data;
length=p_len;
pos=0;
data = (uint8_t *)p_data;
length = p_len;
pos = 0;
return OK;
}
Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) {
Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V(!files, ERR_FILE_NOT_FOUND);
String name = fix_path(p_path);
// name = DirAccess::normalize_path(name);
// name = DirAccess::normalize_path(name);
Map<String, Vector<uint8_t> >::Element* E = files->find(name);
Map<String, Vector<uint8_t> >::Element *E = files->find(name);
ERR_FAIL_COND_V(!E, ERR_FILE_NOT_FOUND);
data = &(E->get()[0]);
@@ -149,7 +148,7 @@ uint8_t FileAccessMemory::get_8() const {
return ret;
}
int FileAccessMemory::get_buffer(uint8_t *p_dst,int p_length) const {
int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!data, -1);
@@ -178,7 +177,7 @@ void FileAccessMemory::store_8(uint8_t p_byte) {
data[pos++] = p_byte;
}
void FileAccessMemory::store_buffer(const uint8_t *p_src,int p_length) {
void FileAccessMemory::store_buffer(const uint8_t *p_src, int p_length) {
int left = length - pos;
int write = MIN(p_length, left);

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -33,19 +34,18 @@
class FileAccessMemory : public FileAccess {
uint8_t* data;
uint8_t *data;
int length;
mutable int pos;
static FileAccess* create();
static FileAccess *create();
public:
static void register_file(String p_name, Vector<uint8_t> p_data);
static void cleanup();
virtual Error open_custom(const uint8_t* p_data, int p_len); ///< open a file
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual Error open_custom(const uint8_t *p_data, int p_len); ///< open a file
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
@@ -58,18 +58,16 @@ public:
virtual uint8_t get_8() const; ///< get a byte
virtual int get_buffer(uint8_t *p_dst,int p_length) const; ///< get an array of bytes
virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes
virtual Error get_error() const; ///< get last error
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual void store_buffer(const uint8_t *p_src,int p_length); ///< store an array of bytes
virtual bool file_exists(const String& p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String& p_file) { return 0; }
virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) { return 0; }
FileAccessMemory();
};

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -27,19 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "file_access_network.h"
#include "marshalls.h"
#include "globals.h"
#include "os/os.h"
#include "io/ip.h"
#include "marshalls.h"
#include "os/os.h"
//#define DEBUG_PRINT(m_p) print_line(m_p)
//#define DEBUG_TIME(m_what) printf("MS: %s - %lli\n",m_what,OS::get_singleton()->get_ticks_usec());
#define DEBUG_PRINT(m_p)
#define DEBUG_TIME(m_what)
void FileAccessNetworkClient::lock_mutex() {
mutex->lock();
@@ -50,59 +48,55 @@ void FileAccessNetworkClient::unlock_mutex() {
lockcount--;
mutex->unlock();
}
void FileAccessNetworkClient::put_32(int p_32) {
uint8_t buf[4];
encode_uint32(p_32,buf);
client->put_data(buf,4);
DEBUG_PRINT("put32: "+itos(p_32));
encode_uint32(p_32, buf);
client->put_data(buf, 4);
DEBUG_PRINT("put32: " + itos(p_32));
}
void FileAccessNetworkClient::put_64(int64_t p_64) {
uint8_t buf[8];
encode_uint64(p_64,buf);
client->put_data(buf,8);
DEBUG_PRINT("put64: "+itos(p_64));
encode_uint64(p_64, buf);
client->put_data(buf, 8);
DEBUG_PRINT("put64: " + itos(p_64));
}
int FileAccessNetworkClient::get_32() {
uint8_t buf[4];
client->get_data(buf,4);
client->get_data(buf, 4);
return decode_uint32(buf);
}
int64_t FileAccessNetworkClient::get_64() {
uint8_t buf[8];
client->get_data(buf,8);
client->get_data(buf, 8);
return decode_uint64(buf);
}
void FileAccessNetworkClient::_thread_func() {
client->set_nodelay(true);
while(!quit) {
while (!quit) {
DEBUG_PRINT("SEM WAIT - "+itos(sem->get()));
DEBUG_PRINT("SEM WAIT - " + itos(sem->get()));
Error err = sem->wait();
DEBUG_TIME("sem_unlock");
//DEBUG_PRINT("semwait returned "+itos(werr));
DEBUG_PRINT("MUTEX LOCK "+itos(lockcount));
DEBUG_PRINT("MUTEX LOCK " + itos(lockcount));
DEBUG_PRINT("POPO");
DEBUG_PRINT("PEPE");
lock_mutex();
DEBUG_PRINT("MUTEX PASS");
blockrequest_mutex->lock();
while(block_requests.size()) {
while (block_requests.size()) {
put_32(block_requests.front()->get().id);
put_32(FileAccessNetwork::COMMAND_READ_BLOCK);
put_64(block_requests.front()->get().offset);
@@ -117,35 +111,32 @@ void FileAccessNetworkClient::_thread_func() {
int id = get_32();
int response = get_32();
DEBUG_PRINT("GET RESPONSE: "+itos(response));
DEBUG_PRINT("GET RESPONSE: " + itos(response));
FileAccessNetwork *fa=NULL;
FileAccessNetwork *fa = NULL;
if (response!=FileAccessNetwork::RESPONSE_DATA) {
if (response != FileAccessNetwork::RESPONSE_DATA) {
ERR_FAIL_COND(!accesses.has(id));
}
if (accesses.has(id))
fa=accesses[id];
fa = accesses[id];
switch(response) {
switch (response) {
case FileAccessNetwork::RESPONSE_OPEN: {
DEBUG_TIME("sem_open");
int status = get_32();
if (status!=OK) {
fa->_respond(0,Error(status));
if (status != OK) {
fa->_respond(0, Error(status));
} else {
uint64_t len = get_64();
fa->_respond(len,Error(status));
fa->_respond(len, Error(status));
}
fa->sem->post();
} break;
case FileAccessNetwork::RESPONSE_DATA: {
@@ -154,104 +145,95 @@ void FileAccessNetworkClient::_thread_func() {
Vector<uint8_t> block;
block.resize(len);
client->get_data(block.ptr(),len);
client->get_data(block.ptr(), len);
if (fa) //may have been queued
fa->_set_block(offset,block);
fa->_set_block(offset, block);
} break;
case FileAccessNetwork::RESPONSE_FILE_EXISTS: {
int status = get_32();
fa->exists_modtime=status!=0;
fa->exists_modtime = status != 0;
fa->sem->post();
} break;
case FileAccessNetwork::RESPONSE_GET_MODTIME: {
uint64_t status = get_64();
fa->exists_modtime=status;
fa->exists_modtime = status;
fa->sem->post();
} break;
}
unlock_mutex();
}
}
void FileAccessNetworkClient::_thread_func(void *s) {
FileAccessNetworkClient *self =(FileAccessNetworkClient*)s;
FileAccessNetworkClient *self = (FileAccessNetworkClient *)s;
self->_thread_func();
}
Error FileAccessNetworkClient::connect(const String& p_host,int p_port,const String& p_password) {
Error FileAccessNetworkClient::connect(const String &p_host, int p_port, const String &p_password) {
IP_Address ip;
if (p_host.is_valid_ip_address()) {
ip=p_host;
ip = p_host;
} else {
ip=IP::get_singleton()->resolve_hostname(p_host);
ip = IP::get_singleton()->resolve_hostname(p_host);
}
DEBUG_PRINT("IP: "+String(ip)+" port "+itos(p_port));
Error err = client->connect(ip,p_port);
ERR_FAIL_COND_V(err,err);
while(client->get_status()==StreamPeerTCP::STATUS_CONNECTING) {
//DEBUG_PRINT("trying to connect....");
DEBUG_PRINT("IP: " + String(ip) + " port " + itos(p_port));
Error err = client->connect(ip, p_port);
ERR_FAIL_COND_V(err, err);
while (client->get_status() == StreamPeerTCP::STATUS_CONNECTING) {
//DEBUG_PRINT("trying to connect....");
OS::get_singleton()->delay_usec(1000);
}
if (client->get_status()!=StreamPeerTCP::STATUS_CONNECTED) {
if (client->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
return ERR_CANT_CONNECT;
}
CharString cs = p_password.utf8();
put_32(cs.length());
client->put_data((const uint8_t*)cs.ptr(),cs.length());
client->put_data((const uint8_t *)cs.ptr(), cs.length());
int e = get_32();
if (e!=OK) {
if (e != OK) {
return ERR_INVALID_PARAMETER;
}
thread = Thread::create(_thread_func,this);
thread = Thread::create(_thread_func, this);
return OK;
}
FileAccessNetworkClient *FileAccessNetworkClient::singleton=NULL;
FileAccessNetworkClient *FileAccessNetworkClient::singleton = NULL;
FileAccessNetworkClient::FileAccessNetworkClient() {
thread=NULL;
thread = NULL;
mutex = Mutex::create();
blockrequest_mutex = Mutex::create();
quit=false;
singleton=this;
last_id=0;
client = Ref<StreamPeerTCP>( StreamPeerTCP::create_ref() );
sem=Semaphore::create();
lockcount=0;
quit = false;
singleton = this;
last_id = 0;
client = Ref<StreamPeerTCP>(StreamPeerTCP::create_ref());
sem = Semaphore::create();
lockcount = 0;
}
FileAccessNetworkClient::~FileAccessNetworkClient() {
if (thread) {
quit=true;
quit = true;
sem->post();
Thread::wait_to_finish(thread);
memdelete(thread);
@@ -260,72 +242,64 @@ FileAccessNetworkClient::~FileAccessNetworkClient() {
memdelete(blockrequest_mutex);
memdelete(mutex);
memdelete(sem);
}
void FileAccessNetwork::_set_block(size_t p_offset,const Vector<uint8_t>& p_block) {
void FileAccessNetwork::_set_block(size_t p_offset, const Vector<uint8_t> &p_block) {
int page = p_offset/page_size;
ERR_FAIL_INDEX(page,pages.size());
if (page<pages.size()-1) {
ERR_FAIL_COND(p_block.size()!=page_size);
int page = p_offset / page_size;
ERR_FAIL_INDEX(page, pages.size());
if (page < pages.size() - 1) {
ERR_FAIL_COND(p_block.size() != page_size);
} else {
ERR_FAIL_COND( (p_block.size() != (total_size%page_size)));
ERR_FAIL_COND((p_block.size() != (total_size % page_size)));
}
buffer_mutex->lock();
pages[page].buffer=p_block;
pages[page].queued=false;
pages[page].buffer = p_block;
pages[page].queued = false;
buffer_mutex->unlock();
if (waiting_on_page==page) {
waiting_on_page=-1;
if (waiting_on_page == page) {
waiting_on_page = -1;
page_sem->post();
}
}
void FileAccessNetwork::_respond(size_t p_len, Error p_status) {
void FileAccessNetwork::_respond(size_t p_len,Error p_status) {
DEBUG_PRINT("GOT RESPONSE - len: "+itos(p_len)+" status: "+itos(p_status));
response=p_status;
if (response!=OK)
DEBUG_PRINT("GOT RESPONSE - len: " + itos(p_len) + " status: " + itos(p_status));
response = p_status;
if (response != OK)
return;
opened=true;
total_size=p_len;
int pc = ((total_size-1)/page_size)+1;
opened = true;
total_size = p_len;
int pc = ((total_size - 1) / page_size) + 1;
pages.resize(pc);
}
Error FileAccessNetwork::_open(const String& p_path, int p_mode_flags) {
Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V(p_mode_flags!=READ,ERR_UNAVAILABLE);
ERR_FAIL_COND_V(p_mode_flags != READ, ERR_UNAVAILABLE);
if (opened)
close();
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
DEBUG_PRINT("open: "+p_path);
DEBUG_PRINT("open: " + p_path);
DEBUG_TIME("open_begin");
nc->lock_mutex();
nc->put_32(id);
nc->accesses[id]=this;
nc->accesses[id] = this;
nc->put_32(COMMAND_OPEN_FILE);
CharString cs =p_path.utf8();
CharString cs = p_path.utf8();
nc->put_32(cs.length());
nc->client->put_data((const uint8_t*)cs.ptr(),cs.length());
pos=0;
eof_flag=false;
last_page=-1;
last_page_buff=NULL;
nc->client->put_data((const uint8_t *)cs.ptr(), cs.length());
pos = 0;
eof_flag = false;
last_page = -1;
last_page_buff = NULL;
// buffers.clear();
// buffers.clear();
nc->unlock_mutex();
DEBUG_PRINT("OPEN POST");
DEBUG_TIME("open_post");
@@ -338,7 +312,7 @@ Error FileAccessNetwork::_open(const String& p_path, int p_mode_flags) {
return response;
}
void FileAccessNetwork::close(){
void FileAccessNetwork::close() {
if (!opened)
return;
@@ -350,110 +324,103 @@ void FileAccessNetwork::close(){
nc->put_32(id);
nc->put_32(COMMAND_CLOSE);
pages.clear();
opened=false;
opened = false;
nc->unlock_mutex();
}
bool FileAccessNetwork::is_open() const{
bool FileAccessNetwork::is_open() const {
return opened;
}
void FileAccessNetwork::seek(size_t p_position){
void FileAccessNetwork::seek(size_t p_position) {
ERR_FAIL_COND(!opened);
eof_flag=p_position>total_size;
eof_flag = p_position > total_size;
if (p_position>=total_size) {
p_position=total_size;
if (p_position >= total_size) {
p_position = total_size;
}
pos=p_position;
pos = p_position;
}
void FileAccessNetwork::seek_end(int64_t p_position){
seek(total_size+p_position);
void FileAccessNetwork::seek_end(int64_t p_position) {
seek(total_size + p_position);
}
size_t FileAccessNetwork::get_pos() const{
size_t FileAccessNetwork::get_pos() const {
ERR_FAIL_COND_V(!opened,0);
ERR_FAIL_COND_V(!opened, 0);
return pos;
}
size_t FileAccessNetwork::get_len() const{
size_t FileAccessNetwork::get_len() const {
ERR_FAIL_COND_V(!opened,0);
ERR_FAIL_COND_V(!opened, 0);
return total_size;
}
bool FileAccessNetwork::eof_reached() const{
bool FileAccessNetwork::eof_reached() const {
ERR_FAIL_COND_V(!opened,false);
ERR_FAIL_COND_V(!opened, false);
return eof_flag;
}
uint8_t FileAccessNetwork::get_8() const{
uint8_t FileAccessNetwork::get_8() const {
uint8_t v;
get_buffer(&v,1);
get_buffer(&v, 1);
return v;
}
void FileAccessNetwork::_queue_page(int p_page) const {
if (p_page>=pages.size())
if (p_page >= pages.size())
return;
if (pages[p_page].buffer.empty() && !pages[p_page].queued) {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->blockrequest_mutex->lock();
FileAccessNetworkClient::BlockRequest br;
br.id=id;
br.offset=size_t(p_page)*page_size;
br.size=page_size;
br.id = id;
br.offset = size_t(p_page) * page_size;
br.size = page_size;
nc->block_requests.push_back(br);
pages[p_page].queued=true;
pages[p_page].queued = true;
nc->blockrequest_mutex->unlock();
DEBUG_PRINT("QUEUE PAGE POST");
nc->sem->post();
DEBUG_PRINT("queued "+itos(p_page));
DEBUG_PRINT("queued " + itos(p_page));
}
}
int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const{
int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
//bool eof=false;
if (pos+p_length>total_size) {
eof_flag=true;
if (pos + p_length > total_size) {
eof_flag = true;
}
if (pos+p_length>=total_size) {
p_length=total_size-pos;
if (pos + p_length >= total_size) {
p_length = total_size - pos;
}
// FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
// FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
uint8_t *buff=last_page_buff;
uint8_t *buff = last_page_buff;
for(int i=0;i<p_length;i++) {
for (int i = 0; i < p_length; i++) {
int page=pos/page_size;
int page = pos / page_size;
if (page!=last_page) {
if (page != last_page) {
buffer_mutex->lock();
if (pages[page].buffer.empty()) {
//fuck
waiting_on_page=page;
for(int j=0;j<read_ahead;j++) {
waiting_on_page = page;
for (int j = 0; j < read_ahead; j++) {
_queue_page(page+j);
_queue_page(page + j);
}
buffer_mutex->unlock();
DEBUG_PRINT("wait");
@@ -461,30 +428,30 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const{
DEBUG_PRINT("done");
} else {
for(int j=0;j<read_ahead;j++) {
for (int j = 0; j < read_ahead; j++) {
_queue_page(page+j);
_queue_page(page + j);
}
buff=pages[page].buffer.ptr();
buff = pages[page].buffer.ptr();
//queue pages
buffer_mutex->unlock();
}
buff=pages[page].buffer.ptr();
last_page_buff=buff;
last_page=page;
buff = pages[page].buffer.ptr();
last_page_buff = buff;
last_page = page;
}
p_dst[i]=buff[pos-uint64_t(page)*page_size];
p_dst[i] = buff[pos - uint64_t(page) * page_size];
pos++;
}
return p_length;
}
Error FileAccessNetwork::get_error() const{
Error FileAccessNetwork::get_error() const {
return pos==total_size?ERR_FILE_EOF:OK;
return pos == total_size ? ERR_FILE_EOF : OK;
}
void FileAccessNetwork::store_8(uint8_t p_dest) {
@@ -492,63 +459,59 @@ void FileAccessNetwork::store_8(uint8_t p_dest) {
ERR_FAIL();
}
bool FileAccessNetwork::file_exists(const String& p_path){
bool FileAccessNetwork::file_exists(const String &p_path) {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
nc->put_32(id);
nc->put_32(COMMAND_FILE_EXISTS);
CharString cs=p_path.utf8();
CharString cs = p_path.utf8();
nc->put_32(cs.length());
nc->client->put_data((const uint8_t*)cs.ptr(),cs.length());
nc->client->put_data((const uint8_t *)cs.ptr(), cs.length());
nc->unlock_mutex();
DEBUG_PRINT("FILE EXISTS POST");
nc->sem->post();
sem->wait();
return exists_modtime!=0;
return exists_modtime != 0;
}
uint64_t FileAccessNetwork::_get_modified_time(const String& p_file){
uint64_t FileAccessNetwork::_get_modified_time(const String &p_file) {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
nc->put_32(id);
nc->put_32(COMMAND_GET_MODTIME);
CharString cs=p_file.utf8();
CharString cs = p_file.utf8();
nc->put_32(cs.length());
nc->client->put_data((const uint8_t*)cs.ptr(),cs.length());
nc->client->put_data((const uint8_t *)cs.ptr(), cs.length());
nc->unlock_mutex();
DEBUG_PRINT("MODTIME POST");
nc->sem->post();
sem->wait();
return exists_modtime;
}
FileAccessNetwork::FileAccessNetwork() {
eof_flag=false;
opened=false;
pos=0;
sem=Semaphore::create();
page_sem=Semaphore::create();
buffer_mutex=Mutex::create();
eof_flag = false;
opened = false;
pos = 0;
sem = Semaphore::create();
page_sem = Semaphore::create();
buffer_mutex = Mutex::create();
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
id=nc->last_id++;
nc->accesses[id]=this;
id = nc->last_id++;
nc->accesses[id] = this;
nc->unlock_mutex();
page_size = GLOBAL_DEF("remote_fs/page_size",65536);
read_ahead = GLOBAL_DEF("remote_fs/page_read_ahead",4);
max_pages = GLOBAL_DEF("remote_fs/max_pages",20);
last_activity_val=0;
waiting_on_page=-1;
last_page=-1;
page_size = GLOBAL_DEF("remote_fs/page_size", 65536);
read_ahead = GLOBAL_DEF("remote_fs/page_read_ahead", 4);
max_pages = GLOBAL_DEF("remote_fs/max_pages", 20);
last_activity_val = 0;
waiting_on_page = -1;
last_page = -1;
}
FileAccessNetwork::~FileAccessNetwork() {
@@ -560,8 +523,7 @@ FileAccessNetwork::~FileAccessNetwork() {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
id=nc->last_id++;
id = nc->last_id++;
nc->accesses.erase(id);
nc->unlock_mutex();
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,16 +30,15 @@
#ifndef FILE_ACCESS_NETWORK_H
#define FILE_ACCESS_NETWORK_H
#include "io/stream_peer_tcp.h"
#include "os/file_access.h"
#include "os/semaphore.h"
#include "os/thread.h"
#include "io/stream_peer_tcp.h"
class FileAccessNetwork;
class FileAccessNetworkClient {
struct BlockRequest {
int id;
@@ -55,7 +55,7 @@ class FileAccessNetworkClient {
bool quit;
Mutex *mutex;
Mutex *blockrequest_mutex;
Map<int,FileAccessNetwork*> accesses;
Map<int, FileAccessNetwork *> accesses;
Ref<StreamPeerTCP> client;
int last_id;
@@ -72,18 +72,16 @@ class FileAccessNetworkClient {
void lock_mutex();
void unlock_mutex();
friend class FileAccessNetwork;
friend class FileAccessNetwork;
static FileAccessNetworkClient *singleton;
public:
static FileAccessNetworkClient *get_singleton() { return singleton; }
Error connect(const String& p_host,int p_port,const String& p_password="");
Error connect(const String &p_host, int p_port, const String &p_password = "");
FileAccessNetworkClient();
~FileAccessNetworkClient();
};
class FileAccessNetwork : public FileAccess {
@@ -109,21 +107,23 @@ class FileAccessNetwork : public FileAccess {
int activity;
bool queued;
Vector<uint8_t> buffer;
Page() { activity=0; queued=false; }
Page() {
activity = 0;
queued = false;
}
};
mutable Vector< Page > pages;
mutable Vector<Page> pages;
mutable Error response;
uint64_t exists_modtime;
friend class FileAccessNetworkClient;
friend class FileAccessNetworkClient;
void _queue_page(int p_page) const;
void _respond(size_t p_len,Error p_status);
void _set_block(size_t p_offset,const Vector<uint8_t>& p_block);
void _respond(size_t p_len, Error p_status);
void _set_block(size_t p_offset, const Vector<uint8_t> &p_block);
public:
enum Command {
COMMAND_OPEN_FILE,
COMMAND_READ_BLOCK,
@@ -139,13 +139,12 @@ public:
RESPONSE_GET_MODTIME,
};
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual size_t get_pos() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
@@ -158,9 +157,9 @@ public:
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual bool file_exists(const String& p_path); ///< return true if a file exists
virtual bool file_exists(const String &p_path); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String& p_file);
virtual uint64_t _get_modified_time(const String &p_file);
FileAccessNetwork();
~FileAccessNetwork();

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -33,9 +34,9 @@
#define PACK_VERSION 0
Error PackedData::add_pack(const String& p_path) {
Error PackedData::add_pack(const String &p_path) {
for (int i=0; i<sources.size(); i++) {
for (int i = 0; i < sources.size(); i++) {
if (sources[i]->try_open_pack(p_path)) {
@@ -46,7 +47,7 @@ Error PackedData::add_pack(const String& p_path) {
return ERR_FILE_UNRECOGNIZED;
};
void PackedData::add_path(const String& pkg_path, const String& path, uint64_t ofs, uint64_t size,const uint8_t* p_md5, PackSource* p_src) {
void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src) {
PathMD5 pmd5(path.md5_buffer());
//printf("adding path %ls, %lli, %lli\n", path.c_str(), pmd5.a, pmd5.b);
@@ -54,35 +55,35 @@ void PackedData::add_path(const String& pkg_path, const String& path, uint64_t o
bool exists = files.has(pmd5);
PackedFile pf;
pf.pack=pkg_path;
pf.offset=ofs;
pf.size=size;
for(int i=0;i<16;i++)
pf.md5[i]=p_md5[i];
pf.pack = pkg_path;
pf.offset = ofs;
pf.size = size;
for (int i = 0; i < 16; i++)
pf.md5[i] = p_md5[i];
pf.src = p_src;
files[pmd5]=pf;
files[pmd5] = pf;
if (!exists) {
//search for dir
String p = path.replace_first("res://","");
PackedDir *cd=root;
String p = path.replace_first("res://", "");
PackedDir *cd = root;
if (p.find("/")!=-1) { //in a subdir
if (p.find("/") != -1) { //in a subdir
Vector<String> ds=p.get_base_dir().split("/");
Vector<String> ds = p.get_base_dir().split("/");
for(int j=0;j<ds.size();j++) {
for (int j = 0; j < ds.size(); j++) {
if (!cd->subdirs.has(ds[j])) {
PackedDir *pd = memnew( PackedDir );
pd->name=ds[j];
pd->parent=cd;
cd->subdirs[pd->name]=pd;
cd=pd;
PackedDir *pd = memnew(PackedDir);
pd->name = ds[j];
pd->parent = cd;
cd->subdirs[pd->name] = pd;
cd = pd;
} else {
cd=cd->subdirs[ds[j]];
cd = cd->subdirs[ds[j]];
}
}
}
@@ -97,61 +98,59 @@ void PackedData::add_pack_source(PackSource *p_source) {
}
};
PackedData *PackedData::singleton=NULL;
PackedData *PackedData::singleton = NULL;
PackedData::PackedData() {
singleton=this;
root=memnew(PackedDir);
root->parent=NULL;
disabled=false;
singleton = this;
root = memnew(PackedDir);
root->parent = NULL;
disabled = false;
add_pack_source(memnew(PackedSourcePCK));
}
void PackedData::_free_packed_dirs(PackedDir *p_dir) {
for (Map<String,PackedDir*>::Element *E=p_dir->subdirs.front();E;E=E->next())
for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next())
_free_packed_dirs(E->get());
memdelete(p_dir);
}
PackedData::~PackedData() {
for(int i=0;i<sources.size();i++) {
for (int i = 0; i < sources.size(); i++) {
memdelete(sources[i]);
}
_free_packed_dirs(root);
}
//////////////////////////////////////////////////////////////////
bool PackedSourcePCK::try_open_pack(const String& p_path) {
bool PackedSourcePCK::try_open_pack(const String &p_path) {
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f)
return false;
//printf("try open %ls!\n", p_path.c_str());
uint32_t magic= f->get_32();
uint32_t magic = f->get_32();
if (magic != 0x43504447) {
//maybe at he end.... self contained exe
f->seek_end();
f->seek( f->get_pos() -4 );
f->seek(f->get_pos() - 4);
magic = f->get_32();
if (magic != 0x43504447) {
memdelete(f);
return false;
}
f->seek( f->get_pos() -12 );
f->seek(f->get_pos() - 12);
uint64_t ds = f->get_64();
f->seek( f->get_pos() -ds-8 );
f->seek(f->get_pos() - ds - 8);
magic = f->get_32();
if (magic != 0x43504447) {
@@ -159,7 +158,6 @@ bool PackedSourcePCK::try_open_pack(const String& p_path) {
memdelete(f);
return false;
}
}
uint32_t version = f->get_32();
@@ -167,25 +165,25 @@ bool PackedSourcePCK::try_open_pack(const String& p_path) {
uint32_t ver_minor = f->get_32();
uint32_t ver_rev = f->get_32();
ERR_EXPLAIN("Pack version newer than supported by engine: "+itos(version));
ERR_FAIL_COND_V( version > PACK_VERSION, ERR_INVALID_DATA);
ERR_EXPLAIN("Pack created with a newer version of the engine: "+itos(ver_major)+"."+itos(ver_minor)+"."+itos(ver_rev));
ERR_FAIL_COND_V( ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), ERR_INVALID_DATA);
ERR_EXPLAIN("Pack version newer than supported by engine: " + itos(version));
ERR_FAIL_COND_V(version > PACK_VERSION, ERR_INVALID_DATA);
ERR_EXPLAIN("Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "." + itos(ver_rev));
ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), ERR_INVALID_DATA);
for(int i=0;i<16;i++) {
for (int i = 0; i < 16; i++) {
//reserved
f->get_32();
}
int file_count = f->get_32();
for(int i=0;i<file_count;i++) {
for (int i = 0; i < file_count; i++) {
uint32_t sl = f->get_32();
CharString cs;
cs.resize(sl+1);
f->get_buffer((uint8_t*)cs.ptr(),sl);
cs[sl]=0;
cs.resize(sl + 1);
f->get_buffer((uint8_t *)cs.ptr(), sl);
cs[sl] = 0;
String path;
path.parse_utf8(cs.ptr());
@@ -193,22 +191,21 @@ bool PackedSourcePCK::try_open_pack(const String& p_path) {
uint64_t ofs = f->get_64();
uint64_t size = f->get_64();
uint8_t md5[16];
f->get_buffer(md5,16);
PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5,this);
f->get_buffer(md5, 16);
PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5, this);
};
return true;
};
FileAccess* PackedSourcePCK::get_file(const String &p_path, PackedData::PackedFile* p_file) {
FileAccess *PackedSourcePCK::get_file(const String &p_path, PackedData::PackedFile *p_file) {
return memnew( FileAccessPack(p_path, *p_file));
return memnew(FileAccessPack(p_path, *p_file));
};
//////////////////////////////////////////////////////////////////
Error FileAccessPack::_open(const String& p_path, int p_mode_flags) {
Error FileAccessPack::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_V(ERR_UNAVAILABLE);
return ERR_UNAVAILABLE;
@@ -219,45 +216,44 @@ void FileAccessPack::close() {
f->close();
}
bool FileAccessPack::is_open() const{
bool FileAccessPack::is_open() const {
return f->is_open();
}
void FileAccessPack::seek(size_t p_position){
void FileAccessPack::seek(size_t p_position) {
if (p_position>pf.size) {
eof=true;
if (p_position > pf.size) {
eof = true;
} else {
eof=false;
eof = false;
}
f->seek(pf.offset+p_position);
pos=p_position;
f->seek(pf.offset + p_position);
pos = p_position;
}
void FileAccessPack::seek_end(int64_t p_position){
seek(pf.size+p_position);
void FileAccessPack::seek_end(int64_t p_position) {
seek(pf.size + p_position);
}
size_t FileAccessPack::get_pos() const {
return pos;
}
size_t FileAccessPack::get_len() const{
size_t FileAccessPack::get_len() const {
return pf.size;
}
bool FileAccessPack::eof_reached() const{
bool FileAccessPack::eof_reached() const {
return eof;
}
uint8_t FileAccessPack::get_8() const {
if (pos>=pf.size) {
eof=true;
if (pos >= pf.size) {
eof = true;
return 0;
}
@@ -265,23 +261,22 @@ uint8_t FileAccessPack::get_8() const {
return f->get_8();
}
int FileAccessPack::get_buffer(uint8_t *p_dst,int p_length) const {
int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {
if (eof)
return 0;
int64_t to_read=p_length;
if (to_read+pos > pf.size) {
eof=true;
to_read=int64_t(pf.size)-int64_t(pos);
int64_t to_read = p_length;
if (to_read + pos > pf.size) {
eof = true;
to_read = int64_t(pf.size) - int64_t(pos);
}
pos+=p_length;
pos += p_length;
if (to_read<=0)
if (to_read <= 0)
return 0;
f->get_buffer(p_dst,to_read);
f->get_buffer(p_dst, to_read);
return to_read;
}
@@ -301,32 +296,29 @@ Error FileAccessPack::get_error() const {
void FileAccessPack::store_8(uint8_t p_dest) {
ERR_FAIL();
}
void FileAccessPack::store_buffer(const uint8_t *p_src,int p_length) {
void FileAccessPack::store_buffer(const uint8_t *p_src, int p_length) {
ERR_FAIL();
}
bool FileAccessPack::file_exists(const String& p_name) {
bool FileAccessPack::file_exists(const String &p_name) {
return false;
}
FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file) {
FileAccessPack::FileAccessPack(const String& p_path, const PackedData::PackedFile& p_file) {
pf=p_file;
f=FileAccess::open(pf.pack,FileAccess::READ);
pf = p_file;
f = FileAccess::open(pf.pack, FileAccess::READ);
if (!f) {
ERR_EXPLAIN("Can't open pack-referenced file: "+String(pf.pack));
ERR_EXPLAIN("Can't open pack-referenced file: " + String(pf.pack));
ERR_FAIL_COND(!f);
}
f->seek(pf.offset);
pos=0;
eof=false;
pos = 0;
eof = false;
}
FileAccessPack::~FileAccessPack() {
@@ -334,24 +326,21 @@ FileAccessPack::~FileAccessPack() {
memdelete(f);
}
//////////////////////////////////////////////////////////////////////////////////
// DIR ACCESS
//////////////////////////////////////////////////////////////////////////////////
bool DirAccessPack::list_dir_begin() {
list_dirs.clear();
list_files.clear();
for (Map<String,PackedData::PackedDir*>::Element *E=current->subdirs.front();E;E=E->next()) {
for (Map<String, PackedData::PackedDir *>::Element *E = current->subdirs.front(); E; E = E->next()) {
list_dirs.push_back(E->key());
}
for (Set<String>::Element *E=current->files.front();E;E=E->next()) {
for (Set<String>::Element *E = current->files.front(); E; E = E->next()) {
list_files.push_back(E->get());
}
@@ -359,15 +348,15 @@ bool DirAccessPack::list_dir_begin() {
return true;
}
String DirAccessPack::get_next(){
String DirAccessPack::get_next() {
if (list_dirs.size()) {
cdir=true;
cdir = true;
String d = list_dirs.front()->get();
list_dirs.pop_front();
return d;
} else if (list_files.size()) {
cdir=false;
cdir = false;
String f = list_files.front()->get();
list_files.pop_front();
return f;
@@ -375,11 +364,11 @@ String DirAccessPack::get_next(){
return String();
}
}
bool DirAccessPack::current_is_dir() const{
bool DirAccessPack::current_is_dir() const {
return cdir;
}
bool DirAccessPack::current_is_hidden() const{
bool DirAccessPack::current_is_hidden() const {
return false;
}
@@ -400,18 +389,18 @@ String DirAccessPack::get_drive(int p_drive) {
Error DirAccessPack::change_dir(String p_dir) {
String nd = p_dir.replace("\\","/");
bool absolute=false;
String nd = p_dir.replace("\\", "/");
bool absolute = false;
if (nd.begins_with("res://")) {
nd=nd.replace_first("res://","");
absolute=true;
nd = nd.replace_first("res://", "");
absolute = true;
}
nd=nd.simplify_path();
nd = nd.simplify_path();
if (nd.begins_with("/")) {
nd=nd.replace_first("/","") ;
absolute=true;
nd = nd.replace_first("/", "");
absolute = true;
}
Vector<String> paths = nd.split("/");
@@ -423,18 +412,18 @@ Error DirAccessPack::change_dir(String p_dir) {
else
pd = current;
for(int i=0;i<paths.size();i++) {
for (int i = 0; i < paths.size(); i++) {
String p = paths[i];
if (p==".") {
if (p == ".") {
continue;
} else if (p=="..") {
} else if (p == "..") {
if (pd->parent) {
pd=pd->parent;
pd = pd->parent;
}
} else if (pd->subdirs.has(p)) {
pd=pd->subdirs[p];
pd = pd->subdirs[p];
} else {
@@ -442,29 +431,26 @@ Error DirAccessPack::change_dir(String p_dir) {
}
}
current=pd;
current = pd;
return OK;
}
String DirAccessPack::get_current_dir() {
String p;
PackedData::PackedDir *pd = current;
while(pd->parent) {
while (pd->parent) {
if (pd!=current)
p="/"+p;
p=p+pd->name;
if (pd != current)
p = "/" + p;
p = p + pd->name;
}
return "res://"+p;
return "res://" + p;
}
bool DirAccessPack::file_exists(String p_file){
bool DirAccessPack::file_exists(String p_file) {
return current->files.has(p_file);
}
@@ -474,36 +460,30 @@ bool DirAccessPack::dir_exists(String p_dir) {
return current->subdirs.has(p_dir);
}
Error DirAccessPack::make_dir(String p_dir){
Error DirAccessPack::make_dir(String p_dir) {
return ERR_UNAVAILABLE;
}
Error DirAccessPack::rename(String p_from, String p_to){
Error DirAccessPack::rename(String p_from, String p_to) {
return ERR_UNAVAILABLE;
}
Error DirAccessPack::remove(String p_name){
Error DirAccessPack::remove(String p_name) {
return ERR_UNAVAILABLE;
}
size_t DirAccessPack::get_space_left(){
size_t DirAccessPack::get_space_left() {
return 0;
}
DirAccessPack::DirAccessPack() {
current=PackedData::get_singleton()->root;
cdir=false;
current = PackedData::get_singleton()->root;
cdir = false;
}
DirAccessPack::~DirAccessPack() {
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,18 +30,18 @@
#ifndef FILE_ACCESS_PACK_H
#define FILE_ACCESS_PACK_H
#include "os/file_access.h"
#include "os/dir_access.h"
#include "map.h"
#include "list.h"
#include "map.h"
#include "os/dir_access.h"
#include "os/file_access.h"
#include "print_string.h"
class PackSource;
class PackedData {
friend class FileAccessPack;
friend class DirAccessPack;
friend class PackSource;
friend class FileAccessPack;
friend class DirAccessPack;
friend class PackSource;
public:
struct PackedFile {
@@ -49,21 +50,21 @@ public:
uint64_t offset; //if offset is ZERO, the file was ERASED
uint64_t size;
uint8_t md5[16];
PackSource* src;
PackSource *src;
};
private:
struct PackedDir {
PackedDir *parent;
String name;
Map<String,PackedDir*> subdirs;
Map<String, PackedDir *> subdirs;
Set<String> files;
};
struct PathMD5 {
uint64_t a;
uint64_t b;
bool operator < (const PathMD5& p_md5) const {
bool operator<(const PathMD5 &p_md5) const {
if (p_md5.a == a) {
return b < p_md5.b;
@@ -72,7 +73,7 @@ private:
}
}
bool operator == (const PathMD5& p_md5) const {
bool operator==(const PathMD5 &p_md5) const {
return a == p_md5.a && b == p_md5.b;
};
@@ -81,14 +82,14 @@ private:
};
PathMD5(const Vector<uint8_t> p_buf) {
a = *((uint64_t*)&p_buf[0]);
b = *((uint64_t*)&p_buf[8]);
a = *((uint64_t *)&p_buf[0]);
b = *((uint64_t *)&p_buf[8]);
};
};
Map<PathMD5,PackedFile> files;
Map<PathMD5, PackedFile> files;
Vector<PackSource*> sources;
Vector<PackSource *> sources;
PackedDir *root;
//Map<String,PackedDir*> dirs;
@@ -99,18 +100,17 @@ private:
void _free_packed_dirs(PackedDir *p_dir);
public:
void add_pack_source(PackSource *p_source);
void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src); // for PackSource
void add_pack_source(PackSource* p_source);
void add_path(const String& pkg_path, const String& path, uint64_t ofs, uint64_t size,const uint8_t* p_md5, PackSource* p_src); // for PackSource
void set_disabled(bool p_disabled) { disabled=p_disabled; }
void set_disabled(bool p_disabled) { disabled = p_disabled; }
_FORCE_INLINE_ bool is_disabled() const { return disabled; }
static PackedData *get_singleton() { return singleton; }
Error add_pack(const String& p_path);
Error add_pack(const String &p_path);
_FORCE_INLINE_ FileAccess *try_open_path(const String& p_path);
_FORCE_INLINE_ bool has_path(const String& p_path);
_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path);
_FORCE_INLINE_ bool has_path(const String &p_path);
PackedData();
~PackedData();
@@ -119,21 +119,18 @@ public:
class PackSource {
public:
virtual bool try_open_pack(const String& p_path)=0;
virtual FileAccess* get_file(const String& p_path, PackedData::PackedFile* p_file)=0;
virtual bool try_open_pack(const String &p_path) = 0;
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0;
virtual ~PackSource() {}
};
class PackedSourcePCK : public PackSource {
public:
virtual bool try_open_pack(const String &p_path);
virtual FileAccess* get_file(const String& p_path, PackedData::PackedFile* p_file);
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
};
class FileAccessPack : public FileAccess {
PackedData::PackedFile pf;
@@ -142,17 +139,15 @@ class FileAccessPack : public FileAccess {
mutable bool eof;
FileAccess *f;
virtual Error _open(const String& p_path, int p_mode_flags);
virtual uint64_t _get_modified_time(const String& p_file) { return 0; }
virtual Error _open(const String &p_path, int p_mode_flags);
virtual uint64_t _get_modified_time(const String &p_file) { return 0; }
public:
virtual void close();
virtual bool is_open() const;
virtual void seek(size_t p_position);
virtual void seek_end(int64_t p_position=0);
virtual void seek_end(int64_t p_position = 0);
virtual size_t get_pos() const;
virtual size_t get_len() const;
@@ -160,8 +155,7 @@ public:
virtual uint8_t get_8() const;
virtual int get_buffer(uint8_t *p_dst,int p_length) const;
virtual int get_buffer(uint8_t *p_dst, int p_length) const;
virtual void set_endian_swap(bool p_swap);
@@ -169,38 +163,34 @@ public:
virtual void store_8(uint8_t p_dest);
virtual void store_buffer(const uint8_t *p_src,int p_length);
virtual void store_buffer(const uint8_t *p_src, int p_length);
virtual bool file_exists(const String& p_name);
virtual bool file_exists(const String &p_name);
FileAccessPack(const String& p_path, const PackedData::PackedFile& p_file);
FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file);
~FileAccessPack();
};
FileAccess *PackedData::try_open_path(const String& p_path) {
FileAccess *PackedData::try_open_path(const String &p_path) {
//print_line("try open path " + p_path);
PathMD5 pmd5(p_path.md5_buffer());
Map<PathMD5,PackedFile>::Element *E=files.find(pmd5);
Map<PathMD5, PackedFile>::Element *E = files.find(pmd5);
if (!E)
return NULL; //not found
if (E->get().offset==0)
if (E->get().offset == 0)
return NULL; //was erased
return E->get().src->get_file(p_path, &E->get());
}
bool PackedData::has_path(const String& p_path) {
bool PackedData::has_path(const String &p_path) {
return files.has(PathMD5(p_path.md5_buffer()));
}
class DirAccessPack : public DirAccess {
PackedData::PackedDir *current;
List<String> list_dirs;
@@ -208,7 +198,6 @@ class DirAccessPack : public DirAccess {
bool cdir;
public:
virtual bool list_dir_begin();
virtual String get_next();
virtual bool current_is_dir() const;
@@ -221,7 +210,6 @@ public:
virtual Error change_dir(String p_dir);
virtual String get_current_dir();
virtual bool file_exists(String p_file);
virtual bool dir_exists(String p_dir);
@@ -234,8 +222,6 @@ public:
DirAccessPack();
~DirAccessPack();
};
#endif // FILE_ACCESS_PACK_H

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -30,78 +31,75 @@
#include "file_access_zip.h"
#include "core/os/file_access.h"
#include "core/os/copymem.h"
#include "core/os/file_access.h"
ZipArchive* ZipArchive::instance = NULL;
ZipArchive *ZipArchive::instance = NULL;
extern "C" {
static void* godot_open(void* data, const char* p_fname, int mode) {
static void *godot_open(void *data, const char *p_fname, int mode) {
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
return NULL;
};
FileAccess* f = (FileAccess*)data;
FileAccess *f = (FileAccess *)data;
f->open(p_fname, FileAccess::READ);
return f->is_open()?data:NULL;
return f->is_open() ? data : NULL;
};
static uLong godot_read(void* data, void* fdata, void* buf, uLong size) {
static uLong godot_read(void *data, void *fdata, void *buf, uLong size) {
FileAccess* f = (FileAccess*)data;
f->get_buffer((uint8_t*)buf, size);
FileAccess *f = (FileAccess *)data;
f->get_buffer((uint8_t *)buf, size);
return size;
};
static uLong godot_write(voidpf opaque, voidpf stream, const void* buf, uLong size) {
static uLong godot_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
return 0;
};
static long godot_tell(voidpf opaque, voidpf stream) {
static long godot_tell (voidpf opaque, voidpf stream) {
FileAccess* f = (FileAccess*)opaque;
FileAccess *f = (FileAccess *)opaque;
return f->get_pos();
};
static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
FileAccess* f = (FileAccess*)opaque;
FileAccess *f = (FileAccess *)opaque;
int pos = offset;
switch (origin) {
case ZLIB_FILEFUNC_SEEK_CUR:
pos = f->get_pos() + offset;
break;
case ZLIB_FILEFUNC_SEEK_END:
pos = f->get_len() + offset;
break;
default:
break;
case ZLIB_FILEFUNC_SEEK_CUR:
pos = f->get_pos() + offset;
break;
case ZLIB_FILEFUNC_SEEK_END:
pos = f->get_len() + offset;
break;
default:
break;
};
f->seek(pos);
return 0;
};
static int godot_close(voidpf opaque, voidpf stream) {
FileAccess* f = (FileAccess*)opaque;
FileAccess *f = (FileAccess *)opaque;
f->close();
return 0;
};
static int godot_testerror(voidpf opaque, voidpf stream) {
FileAccess* f = (FileAccess*)opaque;
return f->get_error()!=OK?1:0;
FileAccess *f = (FileAccess *)opaque;
return f->get_error() != OK ? 1 : 0;
};
static voidpf godot_alloc(voidpf opaque, uInt items, uInt size) {
@@ -119,7 +117,7 @@ static void godot_free(voidpf opaque, voidpf address) {
void ZipArchive::close_handle(unzFile p_file) const {
ERR_FAIL_COND(!p_file);
FileAccess* f = (FileAccess*)unzGetOpaque(p_file);
FileAccess *f = (FileAccess *)unzGetOpaque(p_file);
unzCloseCurrentFile(p_file);
unzClose(p_file);
memdelete(f);
@@ -130,7 +128,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
ERR_FAIL_COND_V(!file_exists(p_file), NULL);
File file = files[p_file];
FileAccess* f = FileAccess::open(packages[file.package].filename, FileAccess::READ);
FileAccess *f = FileAccess::open(packages[file.package].filename, FileAccess::READ);
ERR_FAIL_COND_V(!f, NULL);
zlib_filefunc_def io;
@@ -162,7 +160,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
return pkg;
};
bool ZipArchive::try_open_pack(const String& p_name) {
bool ZipArchive::try_open_pack(const String &p_name) {
//printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
if (p_name.extension().nocasecmp_to("zip") != 0 && p_name.extension().nocasecmp_to("pcz") != 0)
@@ -170,7 +168,7 @@ bool ZipArchive::try_open_pack(const String& p_name) {
zlib_filefunc_def io;
FileAccess* f = FileAccess::open(p_name, FileAccess::READ);
FileAccess *f = FileAccess::open(p_name, FileAccess::READ);
if (!f)
return false;
io.opaque = f;
@@ -188,20 +186,20 @@ bool ZipArchive::try_open_pack(const String& p_name) {
unz_global_info64 gi;
int err = unzGetGlobalInfo64(zfile, &gi);
ERR_FAIL_COND_V(err!=UNZ_OK, false);
ERR_FAIL_COND_V(err != UNZ_OK, false);
Package pkg;
pkg.filename = p_name;
pkg.zfile = zfile;
packages.push_back(pkg);
int pkg_num = packages.size()-1;
int pkg_num = packages.size() - 1;
for (unsigned int i=0;i<gi.number_entry;i++) {
for (unsigned int i = 0; i < gi.number_entry; i++) {
char filename_inzip[256];
unz_file_info64 file_info;
err = unzGetCurrentFileInfo64(zfile,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
err = unzGetCurrentFileInfo64(zfile, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
ERR_CONTINUE(err != UNZ_OK);
File f;
@@ -211,11 +209,11 @@ bool ZipArchive::try_open_pack(const String& p_name) {
String fname = String("res://") + filename_inzip;
files[fname] = f;
uint8_t md5[16]={0,0,0,0,0,0,0,0 , 0,0,0,0,0,0,0,0};
uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
PackedData::get_singleton()->add_path(p_name, fname, 1, 0, md5, this);
//printf("packed data add path %ls, %ls\n", p_name.c_str(), fname.c_str());
if ((i+1)<gi.number_entry) {
if ((i + 1) < gi.number_entry) {
unzGoToNextFile(zfile);
};
};
@@ -228,13 +226,12 @@ bool ZipArchive::file_exists(String p_name) const {
return files.has(p_name);
};
FileAccess* ZipArchive::get_file(const String& p_path, PackedData::PackedFile* p_file) {
FileAccess *ZipArchive::get_file(const String &p_path, PackedData::PackedFile *p_file) {
return memnew(FileAccessZip(p_path, *p_file));
};
ZipArchive* ZipArchive::get_singleton() {
ZipArchive *ZipArchive::get_singleton() {
if (instance == NULL) {
instance = memnew(ZipArchive);
@@ -251,9 +248,9 @@ ZipArchive::ZipArchive() {
ZipArchive::~ZipArchive() {
for (int i=0; i<packages.size(); i++) {
for (int i = 0; i < packages.size(); i++) {
FileAccess* f = (FileAccess*)unzGetOpaque(packages[i].zfile);
FileAccess *f = (FileAccess *)unzGetOpaque(packages[i].zfile);
unzClose(packages[i].zfile);
memdelete(f);
};
@@ -261,18 +258,17 @@ ZipArchive::~ZipArchive() {
packages.clear();
};
Error FileAccessZip::_open(const String& p_path, int p_mode_flags) {
Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
close();
ERR_FAIL_COND_V(p_mode_flags & FileAccess::WRITE, FAILED);
ZipArchive* arch = ZipArchive::get_singleton();
ZipArchive *arch = ZipArchive::get_singleton();
ERR_FAIL_COND_V(!arch, FAILED);
zfile = arch->get_file_handle(p_path);
ERR_FAIL_COND_V(!zfile, FAILED);
int err = unzGetCurrentFileInfo64(zfile,&file_info,NULL,0,NULL,0,NULL,0);
int err = unzGetCurrentFileInfo64(zfile, &file_info, NULL, 0, NULL, 0, NULL, 0);
ERR_FAIL_COND_V(err != UNZ_OK, FAILED);
return OK;
@@ -283,7 +279,7 @@ void FileAccessZip::close() {
if (!zfile)
return;
ZipArchive* arch = ZipArchive::get_singleton();
ZipArchive *arch = ZipArchive::get_singleton();
ERR_FAIL_COND(!arch);
arch->close_handle(zfile);
zfile = NULL;
@@ -332,7 +328,7 @@ uint8_t FileAccessZip::get_8() const {
return ret;
};
int FileAccessZip::get_buffer(uint8_t *p_dst,int p_length) const {
int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!zfile, -1);
at_eof = unzeof(zfile);
@@ -363,13 +359,12 @@ void FileAccessZip::store_8(uint8_t p_dest) {
ERR_FAIL();
};
bool FileAccessZip::file_exists(const String& p_name) {
bool FileAccessZip::file_exists(const String &p_name) {
return false;
};
FileAccessZip::FileAccessZip(const String& p_path, const PackedData::PackedFile& p_file) {
FileAccessZip::FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file) {
zfile = NULL;
_open(p_path, FileAccess::READ);

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,15 +32,14 @@
#ifndef FILE_ACCESS_Zip_H
#define FILE_ACCESS_Zip_H
#include <stdlib.h>
#include "core/io/file_access_pack.h"
#include "unzip.h"
#include "map.h"
#include "unzip.h"
#include <stdlib.h>
class ZipArchive : public PackSource {
public:
struct File {
int package;
@@ -50,23 +50,20 @@ public:
};
};
private:
struct Package {
String filename;
unzFile zfile;
};
Vector<Package> packages;
Map<String,File> files;
Map<String, File> files;
static ZipArchive* instance;
static ZipArchive *instance;
FileAccess::CreateFunc fa_create_func;
public:
void close_handle(unzFile p_file) const;
unzFile get_file_handle(String p_file) const;
@@ -74,49 +71,47 @@ public:
bool file_exists(String p_name) const;
virtual bool try_open_pack(const String& p_path);
FileAccess* get_file(const String& p_path, PackedData::PackedFile* p_file);
virtual bool try_open_pack(const String &p_path);
FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
static ZipArchive* get_singleton();
static ZipArchive *get_singleton();
ZipArchive();
~ZipArchive();
};
class FileAccessZip : public FileAccess {
unzFile zfile;
unz_file_info64 file_info;
unz_file_info64 file_info;
mutable bool at_eof;
ZipArchive* archive;
ZipArchive *archive;
public:
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual size_t get_pos() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
virtual bool eof_reached() const; ///< reading passed EOF
virtual uint8_t get_8() const; ///< get a byte
virtual int get_buffer(uint8_t *p_dst,int p_length) const;
virtual int get_buffer(uint8_t *p_dst, int p_length) const;
virtual Error get_error() const; ///< get last error
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual bool file_exists(const String& p_name); ///< return true if a file exists
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String& p_file) { return 0; } // todo
virtual uint64_t _get_modified_time(const String &p_file) { return 0; } // todo
FileAccessZip(const String& p_path, const PackedData::PackedFile& p_file);
FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file);
~FileAccessZip();
};

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,17 +30,16 @@
#ifndef HTTP_CLIENT_H
#define HTTP_CLIENT_H
#include "io/ip.h"
#include "io/stream_peer.h"
#include "io/stream_peer_tcp.h"
#include "io/ip.h"
#include "reference.h"
class HTTPClient : public Reference {
OBJ_TYPE(HTTPClient,Reference);
public:
OBJ_TYPE(HTTPClient, Reference);
public:
enum ResponseCode {
// 1xx informational
@@ -131,7 +131,6 @@ public:
};
private:
Status status;
IP::ResolverID resolving;
int conn_port;
@@ -159,21 +158,19 @@ private:
Dictionary _get_response_headers_as_dictionary();
int read_chunk_size;
Error _get_http_data(uint8_t* p_buffer, int p_bytes,int &r_received);
Error _get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received);
public:
//Error connect_and_get(const String& p_url,bool p_verify_host=true); //connects to a full url and perform request
Error connect(const String &p_host,int p_port,bool p_ssl=false,bool p_verify_host=true);
Error connect(const String &p_host, int p_port, bool p_ssl = false, bool p_verify_host = true);
void set_connection(const Ref<StreamPeer>& p_connection);
void set_connection(const Ref<StreamPeer> &p_connection);
Ref<StreamPeer> get_connection() const;
Error request_raw( Method p_method, const String& p_url, const Vector<String>& p_headers,const DVector<uint8_t>& p_body);
Error request( Method p_method, const String& p_url, const Vector<String>& p_headers,const String& p_body=String());
Error send_body_text(const String& p_body);
Error send_body_data(const ByteArray& p_body);
Error request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const DVector<uint8_t> &p_body);
Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body = String());
Error send_body_text(const String &p_body);
Error send_body_data(const ByteArray &p_body);
void close();
@@ -194,7 +191,7 @@ public:
Error poll();
String query_string_from_dict(const Dictionary& p_dict);
String query_string_from_dict(const Dictionary &p_dict);
HTTPClient();
~HTTPClient();

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,90 +30,78 @@
#include "image_loader.h"
#include "print_string.h"
bool ImageFormatLoader::recognize(const String& p_extension) const {
bool ImageFormatLoader::recognize(const String &p_extension) const {
List<String> extensions;
get_recognized_extensions(&extensions);
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
if (E->get().nocasecmp_to(p_extension.extension())==0)
if (E->get().nocasecmp_to(p_extension.extension()) == 0)
return true;
}
return false;
}
Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom) {
Error ImageLoader::load_image(String p_file, Image *p_image, FileAccess *p_custom) {
FileAccess *f=p_custom;
FileAccess *f = p_custom;
if (!f) {
Error err;
f=FileAccess::open(p_file,FileAccess::READ,&err);
f = FileAccess::open(p_file, FileAccess::READ, &err);
if (!f) {
ERR_PRINTS("Error opening file: "+p_file);
ERR_PRINTS("Error opening file: " + p_file);
return err;
}
}
String extension = p_file.extension();
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
if (!loader[i]->recognize(extension))
continue;
Error err = loader[i]->load_image(p_image,f);
if (err!=ERR_FILE_UNRECOGNIZED) {
Error err = loader[i]->load_image(p_image, f);
if (err != ERR_FILE_UNRECOGNIZED) {
if (!p_custom)
memdelete(f);
return err;
}
}
if (!p_custom)
memdelete(f);
return ERR_FILE_UNRECOGNIZED;
}
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
loader[i]->get_recognized_extensions(p_extensions);
}
}
bool ImageLoader::recognize(const String& p_extension) {
bool ImageLoader::recognize(const String &p_extension) {
for (int i=0;i<loader_count;i++) {
for (int i = 0; i < loader_count; i++) {
if (loader[i]->recognize(p_extension))
return true;
}
return false;
}
ImageFormatLoader *ImageLoader::loader[MAX_LOADERS];
int ImageLoader::loader_count=0;
int ImageLoader::loader_count = 0;
void ImageLoader::add_image_format_loader(ImageFormatLoader *p_loader) {
ERR_FAIL_COND(loader_count >=MAX_LOADERS );
loader[loader_count++]=p_loader;
ERR_FAIL_COND(loader_count >= MAX_LOADERS);
loader[loader_count++] = p_loader;
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -30,14 +31,13 @@
#define IMAGE_LOADER_H
#include "image.h"
#include "ustring.h"
#include "os/file_access.h"
#include "list.h"
#include "os/file_access.h"
#include "ustring.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
/**
* @class ImageScanLineLoader
* @author Juan Linietsky <reduzio@gmail.com>
@@ -46,21 +46,19 @@
*/
class ImageLoader;
/**
* @class ImageLoader
* Base Class and singleton for loading images from disk
* Can load images in one go, or by scanline
*/
class ImageFormatLoader {
friend class ImageLoader;
protected:
virtual Error load_image(Image *p_image,FileAccess *p_fileaccess)=0;
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
bool recognize(const String& p_extension) const;
friend class ImageLoader;
protected:
virtual Error load_image(Image *p_image, FileAccess *p_fileaccess) = 0;
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
bool recognize(const String &p_extension) const;
public:
virtual ~ImageFormatLoader() {}
@@ -69,23 +67,19 @@ public:
class ImageLoader {
enum {
MAX_LOADERS=8
MAX_LOADERS = 8
};
static ImageFormatLoader *loader[MAX_LOADERS];
static int loader_count;
protected:
public:
static Error load_image(String p_file,Image *p_image, FileAccess *p_custom=NULL);
static void get_recognized_extensions(List<String> *p_extensions) ;
static bool recognize(const String& p_extension) ;
static Error load_image(String p_file, Image *p_image, FileAccess *p_custom = NULL);
static void get_recognized_extensions(List<String> *p_extensions);
static bool recognize(const String &p_extension);
static void add_image_format_loader(ImageFormatLoader *p_loader);
};
#endif

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -27,15 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "ip.h"
#include "os/thread.h"
#include "os/semaphore.h"
#include "hash_map.h"
#include "os/semaphore.h"
#include "os/thread.h"
VARIANT_ENUM_CAST(IP::ResolverStatus);
/************* RESOLVER ******************/
struct _IP_ResolverPrivate {
struct QueueItem {
@@ -43,11 +43,13 @@ struct _IP_ResolverPrivate {
volatile IP::ResolverStatus status;
IP_Address response;
String hostname;
IP::Type type;
void clear() {
status = IP::RESOLVER_STATUS_NONE;
response = IP_Address();
hostname="";
type = IP::TYPE_NONE;
hostname = "";
};
QueueItem() {
@@ -59,8 +61,8 @@ struct _IP_ResolverPrivate {
IP::ResolverID find_empty_id() const {
for(int i=0;i<IP::RESOLVER_MAX_QUERIES;i++) {
if (queue[i].status==IP::RESOLVER_STATUS_NONE)
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
if (queue[i].status == IP::RESOLVER_STATUS_NONE)
return i;
}
return IP::RESOLVER_INVALID_ID;
@@ -68,132 +70,134 @@ struct _IP_ResolverPrivate {
Semaphore *sem;
Thread* thread;
Thread *thread;
//Semaphore* semaphore;
bool thread_abort;
void resolve_queues() {
for(int i=0;i<IP::RESOLVER_MAX_QUERIES;i++) {
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
if (queue[i].status!=IP::RESOLVER_STATUS_WAITING)
if (queue[i].status != IP::RESOLVER_STATUS_WAITING)
continue;
queue[i].response=IP::get_singleton()->resolve_hostname(queue[i].hostname);
queue[i].response = IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type);
if (queue[i].response.host==0)
queue[i].status=IP::RESOLVER_STATUS_ERROR;
if (!queue[i].response.is_valid())
queue[i].status = IP::RESOLVER_STATUS_ERROR;
else
queue[i].status=IP::RESOLVER_STATUS_DONE;
queue[i].status = IP::RESOLVER_STATUS_DONE;
}
}
static void _thread_function(void *self) {
_IP_ResolverPrivate *ipr=(_IP_ResolverPrivate*)self;
_IP_ResolverPrivate *ipr = (_IP_ResolverPrivate *)self;
while(!ipr->thread_abort) {
while (!ipr->thread_abort) {
ipr->sem->wait();
GLOBAL_LOCK_FUNCTION;
ipr->resolve_queues();
}
}
HashMap<String, IP_Address> cache;
static String get_cache_key(String p_hostname, IP::Type p_type) {
return itos(p_type) + p_hostname;
}
};
IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
GLOBAL_LOCK_FUNCTION;
IP_Address IP::resolve_hostname(const String& p_hostname) {
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
if (resolver->cache.has(key))
return resolver->cache[key];
GLOBAL_LOCK_FUNCTION
if (resolver->cache.has(p_hostname))
return resolver->cache[p_hostname];
IP_Address res = _resolve_hostname(p_hostname);
resolver->cache[p_hostname]=res;
IP_Address res = _resolve_hostname(p_hostname, p_type);
resolver->cache[key] = res;
return res;
}
IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname) {
IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Type p_type) {
GLOBAL_LOCK_FUNCTION
GLOBAL_LOCK_FUNCTION;
ResolverID id = resolver->find_empty_id();
if (id==RESOLVER_INVALID_ID) {
if (id == RESOLVER_INVALID_ID) {
WARN_PRINT("Out of resolver queries");
return id;
}
resolver->queue[id].hostname=p_hostname;
if (resolver->cache.has(p_hostname)) {
resolver->queue[id].response=resolver->cache[p_hostname];
resolver->queue[id].status=IP::RESOLVER_STATUS_DONE;
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
resolver->queue[id].hostname = p_hostname;
resolver->queue[id].type = p_type;
if (resolver->cache.has(key)) {
resolver->queue[id].response = resolver->cache[key];
resolver->queue[id].status = IP::RESOLVER_STATUS_DONE;
} else {
resolver->queue[id].response=IP_Address();
resolver->queue[id].status=IP::RESOLVER_STATUS_WAITING;
resolver->queue[id].response = IP_Address();
resolver->queue[id].status = IP::RESOLVER_STATUS_WAITING;
if (resolver->thread)
resolver->sem->post();
else
resolver->resolve_queues();
}
return id;
}
IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
ERR_FAIL_INDEX_V(p_id,IP::RESOLVER_MAX_QUERIES,IP::RESOLVER_STATUS_NONE);
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP::RESOLVER_STATUS_NONE);
GLOBAL_LOCK_FUNCTION;
ERR_FAIL_COND_V(resolver->queue[p_id].status==IP::RESOLVER_STATUS_NONE,IP::RESOLVER_STATUS_NONE);
ERR_FAIL_COND_V(resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE, IP::RESOLVER_STATUS_NONE);
return resolver->queue[p_id].status;
}
IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
ERR_FAIL_INDEX_V(p_id,IP::RESOLVER_MAX_QUERIES,IP_Address());
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP_Address());
GLOBAL_LOCK_FUNCTION;
if (resolver->queue[p_id].status!=IP::RESOLVER_STATUS_DONE) {
ERR_EXPLAIN("Resolve of '"+resolver->queue[p_id].hostname+"'' didn't complete yet.");
ERR_FAIL_COND_V(resolver->queue[p_id].status!=IP::RESOLVER_STATUS_DONE,IP_Address());
if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) {
ERR_EXPLAIN("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet.");
ERR_FAIL_COND_V(resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE, IP_Address());
}
return resolver->queue[p_id].response;
}
void IP::erase_resolve_item(ResolverID p_id) {
ERR_FAIL_INDEX(p_id,IP::RESOLVER_MAX_QUERIES);
ERR_FAIL_INDEX(p_id, IP::RESOLVER_MAX_QUERIES);
GLOBAL_LOCK_FUNCTION;
resolver->queue[p_id].status=IP::RESOLVER_STATUS_NONE;
resolver->queue[p_id].status = IP::RESOLVER_STATUS_NONE;
}
void IP::clear_cache(const String &p_hostname) {
if (p_hostname.empty()) {
resolver->cache.clear();
} else {
resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_NONE));
resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_IPV4));
resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_IPV6));
resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_ANY));
}
};
Array IP::_get_local_addresses() const {
Array addresses;
List<IP_Address> ip_addresses;
get_local_addresses(&ip_addresses);
for(List<IP_Address>::Element *E=ip_addresses.front();E;E=E->next()) {
for (List<IP_Address>::Element *E = ip_addresses.front(); E; E = E->next()) {
addresses.push_back(E->get());
}
@@ -202,82 +206,82 @@ Array IP::_get_local_addresses() const {
void IP::_bind_methods() {
ObjectTypeDB::bind_method(_MD("resolve_hostname","host"),&IP::resolve_hostname);
ObjectTypeDB::bind_method(_MD("resolve_hostname_queue_item","host"),&IP::resolve_hostname_queue_item);
ObjectTypeDB::bind_method(_MD("get_resolve_item_status","id"),&IP::get_resolve_item_status);
ObjectTypeDB::bind_method(_MD("get_resolve_item_address","id"),&IP::get_resolve_item_address);
ObjectTypeDB::bind_method(_MD("erase_resolve_item","id"),&IP::erase_resolve_item);
ObjectTypeDB::bind_method(_MD("get_local_addresses"),&IP::_get_local_addresses);
ObjectTypeDB::bind_method(_MD("resolve_hostname", "host", "ip_type"), &IP::resolve_hostname, DEFVAL(IP::TYPE_ANY));
ObjectTypeDB::bind_method(_MD("resolve_hostname_queue_item", "host", "ip_type"), &IP::resolve_hostname_queue_item, DEFVAL(IP::TYPE_ANY));
ObjectTypeDB::bind_method(_MD("get_resolve_item_status", "id"), &IP::get_resolve_item_status);
ObjectTypeDB::bind_method(_MD("get_resolve_item_address", "id"), &IP::get_resolve_item_address);
ObjectTypeDB::bind_method(_MD("erase_resolve_item", "id"), &IP::erase_resolve_item);
ObjectTypeDB::bind_method(_MD("get_local_addresses"), &IP::_get_local_addresses);
ObjectTypeDB::bind_method(_MD("clear_cache"), &IP::clear_cache, DEFVAL(""));
BIND_CONSTANT( RESOLVER_STATUS_NONE );
BIND_CONSTANT( RESOLVER_STATUS_WAITING );
BIND_CONSTANT( RESOLVER_STATUS_DONE );
BIND_CONSTANT( RESOLVER_STATUS_ERROR );
BIND_CONSTANT(RESOLVER_STATUS_NONE);
BIND_CONSTANT(RESOLVER_STATUS_WAITING);
BIND_CONSTANT(RESOLVER_STATUS_DONE);
BIND_CONSTANT(RESOLVER_STATUS_ERROR);
BIND_CONSTANT( RESOLVER_MAX_QUERIES );
BIND_CONSTANT( RESOLVER_INVALID_ID );
BIND_CONSTANT(RESOLVER_MAX_QUERIES);
BIND_CONSTANT(RESOLVER_INVALID_ID);
BIND_CONSTANT(TYPE_NONE);
BIND_CONSTANT(TYPE_IPV4);
BIND_CONSTANT(TYPE_IPV6);
BIND_CONSTANT(TYPE_ANY);
}
IP *IP::singleton = NULL;
IP*IP::singleton=NULL;
IP* IP::get_singleton() {
IP *IP::get_singleton() {
return singleton;
}
IP *(*IP::_create)() = NULL;
IP* (*IP::_create)()=NULL;
IP *IP::create() {
IP* IP::create() {
ERR_FAIL_COND_V(singleton,NULL);
ERR_FAIL_COND_V(!_create,NULL);
ERR_FAIL_COND_V(singleton, NULL);
ERR_FAIL_COND_V(!_create, NULL);
return _create();
}
IP::IP() {
singleton=this;
resolver = memnew( _IP_ResolverPrivate );
resolver->sem=NULL;
singleton = this;
resolver = memnew(_IP_ResolverPrivate);
resolver->sem = NULL;
#ifndef NO_THREADS
//resolver->sem = Semaphore::create();
resolver->sem=NULL;
resolver->sem = NULL;
if (resolver->sem) {
resolver->thread_abort=false;
resolver->thread_abort = false;
resolver->thread = Thread::create( _IP_ResolverPrivate::_thread_function,resolver );
resolver->thread = Thread::create(_IP_ResolverPrivate::_thread_function, resolver);
if (!resolver->thread)
memdelete(resolver->sem); //wtf
} else {
resolver->thread=NULL;
resolver->thread = NULL;
}
#else
resolver->sem = NULL;
resolver->thread=NULL;
resolver->thread = NULL;
#endif
}
IP::~IP() {
#ifndef NO_THREADS
if (resolver->thread) {
resolver->thread_abort=true;
resolver->thread_abort = true;
resolver->sem->post();
Thread::wait_to_finish(resolver->thread);
memdelete( resolver->thread );
memdelete( resolver->sem);
memdelete(resolver->thread);
memdelete(resolver->sem);
}
memdelete(resolver);
#endif
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,17 +30,16 @@
#ifndef IP_H
#define IP_H
#include "os/os.h"
#include "io/ip_address.h"
#include "os/os.h"
struct _IP_ResolverPrivate;
class IP : public Object {
OBJ_TYPE( IP, Object );
OBJ_TYPE(IP, Object);
OBJ_CATEGORY("Networking");
public:
public:
enum ResolverStatus {
RESOLVER_STATUS_NONE,
@@ -48,47 +48,52 @@ public:
RESOLVER_STATUS_ERROR,
};
enum {
RESOLVER_MAX_QUERIES = 32,
RESOLVER_INVALID_ID=-1
enum Type {
TYPE_NONE = 0,
TYPE_IPV4 = 1,
TYPE_IPV6 = 2,
TYPE_ANY = 3,
};
enum {
RESOLVER_MAX_QUERIES = 32,
RESOLVER_INVALID_ID = -1
};
typedef int ResolverID;
private:
_IP_ResolverPrivate *resolver;
protected:
static IP*singleton;
protected:
static IP *singleton;
static void _bind_methods();
virtual IP_Address _resolve_hostname(const String& p_hostname)=0;
virtual IP_Address _resolve_hostname(const String &p_hostname, Type p_type = TYPE_ANY) = 0;
Array _get_local_addresses() const;
static IP* (*_create)();
static IP *(*_create)();
public:
IP_Address resolve_hostname(const String& p_hostname);
IP_Address resolve_hostname(const String &p_hostname, Type p_type = TYPE_ANY);
// async resolver hostname
ResolverID resolve_hostname_queue_item(const String& p_hostname);
ResolverID resolve_hostname_queue_item(const String &p_hostname, Type p_type = TYPE_ANY);
ResolverStatus get_resolve_item_status(ResolverID p_id) const;
IP_Address get_resolve_item_address(ResolverID p_id) const;
virtual void get_local_addresses(List<IP_Address> *r_addresses) const=0;
virtual void get_local_addresses(List<IP_Address> *r_addresses) const = 0;
void erase_resolve_item(ResolverID p_id);
static IP* get_singleton();
void clear_cache(const String &p_hostname = "");
static IP* create();
static IP *get_singleton();
static IP *create();
IP();
~IP();
};
VARIANT_ENUM_CAST(IP::Type);
#endif // IP_H

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,29 +33,226 @@ IP_Address::operator Variant() const {
return operator String();
}*/
#include <stdio.h>
#include <string.h>
IP_Address::operator String() const {
return itos(field[0])+"."+itos(field[1])+"."+itos(field[2])+"."+itos(field[3]);
if (!valid)
return "";
if (is_ipv4())
// IPv4 address mapped to IPv6
return itos(field8[12]) + "." + itos(field8[13]) + "." + itos(field8[14]) + "." + itos(field8[15]);
String ret;
for (int i = 0; i < 8; i++) {
if (i > 0)
ret = ret + ":";
uint16_t num = (field8[i * 2] << 8) + field8[i * 2 + 1];
ret = ret + String::num_int64(num, 16);
};
return ret;
}
IP_Address::IP_Address(const String& p_string) {
static void _parse_hex(const String &p_string, int p_start, uint8_t *p_dst) {
host=0;
int slices = p_string.get_slice_count(".");
if (slices!=4) {
ERR_EXPLAIN("Invalid IP Address String: "+p_string);
uint16_t ret = 0;
for (int i = p_start; i < p_start + 4; i++) {
if (i >= p_string.length()) {
break;
};
int n = 0;
CharType c = p_string[i];
if (c >= '0' && c <= '9') {
n = c - '0';
} else if (c >= 'a' && c <= 'f') {
n = 10 + (c - 'a');
} else if (c >= 'A' && c <= 'F') {
n = 10 + (c - 'A');
} else if (c == ':') {
break;
} else {
ERR_EXPLAIN("Invalid character in ipv6 address: " + p_string);
ERR_FAIL();
};
ret = ret << 4;
ret += n;
};
p_dst[0] = ret >> 8;
p_dst[1] = ret & 0xff;
};
void IP_Address::_parse_ipv6(const String &p_string) {
static const int parts_total = 8;
int parts[parts_total] = { 0 };
int parts_count = 0;
bool part_found = false;
bool part_skip = false;
bool part_ipv4 = false;
int parts_idx = 0;
for (int i = 0; i < p_string.length(); i++) {
CharType c = p_string[i];
if (c == ':') {
if (i == 0) {
continue; // next must be a ":"
};
if (!part_found) {
part_skip = true;
parts[parts_idx++] = -1;
};
part_found = false;
} else if (c == '.') {
part_ipv4 = true;
} else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
if (!part_found) {
parts[parts_idx++] = i;
part_found = true;
++parts_count;
};
} else {
ERR_EXPLAIN("Invalid character in IPv6 address: " + p_string);
ERR_FAIL();
};
};
int parts_extra = 0;
if (part_skip) {
parts_extra = parts_total - parts_count;
};
int idx = 0;
for (int i = 0; i < parts_idx; i++) {
if (parts[i] == -1) {
for (int j = 0; j < parts_extra; j++) {
field16[idx++] = 0;
};
continue;
};
if (part_ipv4 && i == parts_idx - 1) {
_parse_ipv4(p_string, parts[i], (uint8_t *)&field16[idx]); // should be the last one
} else {
_parse_hex(p_string, parts[i], (uint8_t *)&(field16[idx++]));
};
};
};
void IP_Address::_parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret) {
String ip;
if (p_start != 0) {
ip = p_string.substr(p_start, p_string.length() - p_start);
} else {
ip = p_string;
};
int slices = ip.get_slice_count(".");
if (slices != 4) {
ERR_EXPLAIN("Invalid IP Address String: " + ip);
ERR_FAIL();
}
for(int i=0;i<4;i++) {
for (int i = 0; i < 4; i++) {
p_ret[i] = ip.get_slicec('.', i).to_int();
}
};
field[i]=p_string.get_slicec('.',i).to_int();
void IP_Address::clear() {
memset(&field8[0], 0, sizeof(field8));
valid = false;
wildcard = false;
};
bool IP_Address::is_ipv4() const {
return (field32[0] == 0 && field32[1] == 0 && field16[4] == 0 && field16[5] == 0xffff);
}
const uint8_t *IP_Address::get_ipv4() const {
ERR_FAIL_COND_V(!is_ipv4(), 0);
return &(field8[12]);
}
void IP_Address::set_ipv4(const uint8_t *p_ip) {
clear();
valid = true;
field16[5] = 0xffff;
field32[3] = *((const uint32_t *)p_ip);
}
const uint8_t *IP_Address::get_ipv6() const {
return field8;
}
void IP_Address::set_ipv6(const uint8_t *p_buf) {
clear();
valid = true;
for (int i = 0; i < 16; i++)
field8[i] = p_buf[i];
}
IP_Address::IP_Address(const String &p_string) {
clear();
if (p_string == "*") {
// Wildcard (not a vaild IP)
wildcard = true;
} else if (p_string.find(":") >= 0) {
// IPv6
_parse_ipv6(p_string);
valid = true;
} else if (p_string.get_slice_count(".") == 4) {
// IPv4 (mapped to IPv6 internally)
field16[5] = 0xffff;
_parse_ipv4(p_string, 0, &field8[12]);
valid = true;
} else {
ERR_PRINT("Invalid IP address");
}
}
IP_Address::IP_Address(uint8_t p_a,uint8_t p_b,uint8_t p_c,uint8_t p_d) {
_FORCE_INLINE_ static void _32_to_buf(uint8_t *p_dst, uint32_t p_n) {
field[0]=p_a;
field[1]=p_b;
field[2]=p_c;
field[3]=p_d;
p_dst[0] = (p_n >> 24) & 0xff;
p_dst[1] = (p_n >> 16) & 0xff;
p_dst[2] = (p_n >> 8) & 0xff;
p_dst[3] = (p_n >> 0) & 0xff;
};
IP_Address::IP_Address(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6) {
clear();
valid = true;
if (!is_v6) {
// Mapped to IPv6
field16[5] = 0xffff;
field8[12] = p_a;
field8[13] = p_b;
field8[14] = p_c;
field8[15] = p_d;
} else {
_32_to_buf(&field8[0], p_a);
_32_to_buf(&field8[4], p_b);
_32_to_buf(&field8[8], p_c);
_32_to_buf(&field8[12], p_d);
}
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -33,24 +34,53 @@
struct IP_Address {
private:
union {
uint8_t field[4];
uint32_t host;
uint8_t field8[16];
uint16_t field16[8];
uint32_t field32[4];
};
bool valid;
bool wildcard;
protected:
void _parse_ipv6(const String &p_string);
void _parse_ipv4(const String &p_string, int p_start, uint8_t *p_ret);
public:
//operator Variant() const;
bool operator==(const IP_Address& p_ip) const {
return host==p_ip.host;
bool operator==(const IP_Address &p_ip) const {
if (p_ip.valid != valid) return false;
if (!valid) return false;
for (int i = 0; i < 4; i++)
if (field32[i] != p_ip.field32[i])
return false;
return true;
}
bool operator!=(const IP_Address& p_ip) const {
return host!=p_ip.host;
bool operator!=(const IP_Address &p_ip) const {
if (p_ip.valid != valid) return true;
if (!valid) return true;
for (int i = 0; i < 4; i++)
if (field32[i] != p_ip.field32[i])
return true;
return false;
}
void clear();
bool is_wildcard() const { return wildcard; }
bool is_valid() const { return valid; }
bool is_ipv4() const;
const uint8_t *get_ipv4() const;
void set_ipv4(const uint8_t *p_ip);
const uint8_t *get_ipv6() const;
void set_ipv6(const uint8_t *buf);
operator String() const;
IP_Address(const String& p_string);
IP_Address(uint8_t p_a,uint8_t p_b,uint8_t p_c,uint8_t p_d);
IP_Address() { host=0; }
IP_Address(const String &p_string);
IP_Address(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6 = false);
IP_Address() { clear(); }
};
#endif // IP_ADDRESS_H

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,7 +30,7 @@
#include "json.h"
#include "print_string.h"
const char * JSON::tk_name[TK_MAX] = {
const char *JSON::tk_name[TK_MAX] = {
"'{'",
"'}'",
"'['",
@@ -42,14 +43,12 @@ const char * JSON::tk_name[TK_MAX] = {
"EOF",
};
String JSON::_print_var(const Variant &p_var) {
String JSON::_print_var(const Variant& p_var) {
switch(p_var.get_type()) {
switch (p_var.get_type()) {
case Variant::NIL: return "null";
case Variant::BOOL: return p_var.operator bool() ? "true": "false";
case Variant::BOOL: return p_var.operator bool() ? "true" : "false";
case Variant::INT: return itos(p_var);
case Variant::REAL: return rtos(p_var);
case Variant::INT_ARRAY:
@@ -59,12 +58,12 @@ String JSON::_print_var(const Variant& p_var) {
String s = "[";
Array a = p_var;
for(int i=0;i<a.size();i++) {
if (i>0)
s+=", ";
s+=_print_var(a[i]);
for (int i = 0; i < a.size(); i++) {
if (i > 0)
s += ", ";
s += _print_var(a[i]);
}
s+="]";
s += "]";
return s;
};
case Variant::DICTIONARY: {
@@ -74,34 +73,31 @@ String JSON::_print_var(const Variant& p_var) {
List<Variant> keys;
d.get_key_list(&keys);
for (List<Variant>::Element *E=keys.front();E;E=E->next()) {
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
if (E!=keys.front())
s+=", ";
s+=_print_var(String(E->get()));
s+=":";
s+=_print_var(d[E->get()]);
if (E != keys.front())
s += ", ";
s += _print_var(String(E->get()));
s += ":";
s += _print_var(d[E->get()]);
}
s+="}";
s += "}";
return s;
};
default: return "\""+String(p_var).json_escape()+"\"";
default: return "\"" + String(p_var).json_escape() + "\"";
}
}
String JSON::print(const Dictionary& p_dict) {
String JSON::print(const Dictionary &p_dict) {
return _print_var(p_dict);
}
Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_token,int &line,String &r_err_str) {
Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token &r_token, int &line, String &r_err_str) {
while (true) {
switch(p_str[idx]) {
switch (p_str[idx]) {
case '\n': {
@@ -110,42 +106,42 @@ Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_toke
break;
};
case 0: {
r_token.type=TK_EOF;
r_token.type = TK_EOF;
return OK;
} break;
case '{': {
r_token.type=TK_CURLY_BRACKET_OPEN;
r_token.type = TK_CURLY_BRACKET_OPEN;
idx++;
return OK;
};
case '}': {
r_token.type=TK_CURLY_BRACKET_CLOSE;
r_token.type = TK_CURLY_BRACKET_CLOSE;
idx++;
return OK;
};
case '[': {
r_token.type=TK_BRACKET_OPEN;
r_token.type = TK_BRACKET_OPEN;
idx++;
return OK;
};
case ']': {
r_token.type=TK_BRACKET_CLOSE;
r_token.type = TK_BRACKET_CLOSE;
idx++;
return OK;
};
case ':': {
r_token.type=TK_COLON;
r_token.type = TK_COLON;
idx++;
return OK;
};
case ',': {
r_token.type=TK_COMMA;
r_token.type = TK_COMMA;
idx++;
return OK;
};
@@ -153,66 +149,62 @@ Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_toke
idx++;
String str;
while(true) {
if (p_str[idx]==0) {
r_err_str="Unterminated String";
while (true) {
if (p_str[idx] == 0) {
r_err_str = "Unterminated String";
return ERR_PARSE_ERROR;
} else if (p_str[idx]=='"') {
} else if (p_str[idx] == '"') {
idx++;
break;
} else if (p_str[idx]=='\\') {
} else if (p_str[idx] == '\\') {
//escaped characters...
idx++;
CharType next = p_str[idx];
if (next==0) {
r_err_str="Unterminated String";
return ERR_PARSE_ERROR;
if (next == 0) {
r_err_str = "Unterminated String";
return ERR_PARSE_ERROR;
}
CharType res=0;
CharType res = 0;
switch(next) {
switch (next) {
case 'b': res=8; break;
case 't': res=9; break;
case 'n': res=10; break;
case 'f': res=12; break;
case 'r': res=13; break;
case 'b': res = 8; break;
case 't': res = 9; break;
case 'n': res = 10; break;
case 'f': res = 12; break;
case 'r': res = 13; break;
case 'u': {
//hexnumbarh - oct is deprecated
for(int j=0;j<4;j++) {
CharType c = p_str[idx+j+1];
if (c==0) {
r_err_str="Unterminated String";
for (int j = 0; j < 4; j++) {
CharType c = p_str[idx + j + 1];
if (c == 0) {
r_err_str = "Unterminated String";
return ERR_PARSE_ERROR;
}
if (!((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F'))) {
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
r_err_str="Malformed hex constant in string";
r_err_str = "Malformed hex constant in string";
return ERR_PARSE_ERROR;
}
CharType v;
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 {
ERR_PRINT("BUG");
v=0;
v = 0;
}
res<<=4;
res|=v;
res <<= 4;
res |= v;
}
idx+=4; //will add at the end anyway
idx += 4; //will add at the end anyway
} break;
//case '\"': res='\"'; break;
@@ -225,253 +217,236 @@ Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_toke
} break;
}
str+=res;
str += res;
} else {
if (p_str[idx]=='\n')
if (p_str[idx] == '\n')
line++;
str+=p_str[idx];
str += p_str[idx];
}
idx++;
}
r_token.type=TK_STRING;
r_token.value=str;
r_token.type = TK_STRING;
r_token.value = str;
return OK;
} break;
default: {
if (p_str[idx]<=32) {
if (p_str[idx] <= 32) {
idx++;
break;
}
if (p_str[idx]=='-' || (p_str[idx]>='0' && p_str[idx]<='9')) {
if (p_str[idx] == '-' || (p_str[idx] >= '0' && p_str[idx] <= '9')) {
//a number
const CharType *rptr;
double number = String::to_double(&p_str[idx],&rptr);
idx+=(rptr - &p_str[idx]);
r_token.type=TK_NUMBER;
r_token.value=number;
double number = String::to_double(&p_str[idx], &rptr);
idx += (rptr - &p_str[idx]);
r_token.type = TK_NUMBER;
r_token.value = number;
return OK;
} else if ((p_str[idx]>='A' && p_str[idx]<='Z') || (p_str[idx]>='a' && p_str[idx]<='z')) {
} else if ((p_str[idx] >= 'A' && p_str[idx] <= 'Z') || (p_str[idx] >= 'a' && p_str[idx] <= 'z')) {
String id;
while((p_str[idx]>='A' && p_str[idx]<='Z') || (p_str[idx]>='a' && p_str[idx]<='z')) {
while ((p_str[idx] >= 'A' && p_str[idx] <= 'Z') || (p_str[idx] >= 'a' && p_str[idx] <= 'z')) {
id+=p_str[idx];
id += p_str[idx];
idx++;
}
r_token.type=TK_IDENTIFIER;
r_token.value=id;
r_token.type = TK_IDENTIFIER;
r_token.value = id;
return OK;
} else {
r_err_str="Unexpected character.";
r_err_str = "Unexpected character.";
return ERR_PARSE_ERROR;
}
}
}
}
return ERR_PARSE_ERROR;
}
Error JSON::_parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
Error JSON::_parse_value(Variant &value,Token& token,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str) {
if (token.type==TK_CURLY_BRACKET_OPEN) {
if (token.type == TK_CURLY_BRACKET_OPEN) {
Dictionary d(true);
Error err = _parse_object(d,p_str,index,p_len,line,r_err_str);
Error err = _parse_object(d, p_str, index, p_len, line, r_err_str);
if (err)
return err;
value=d;
value = d;
return OK;
} else if (token.type==TK_BRACKET_OPEN) {
} else if (token.type == TK_BRACKET_OPEN) {
Array a(true);
Error err = _parse_array(a,p_str,index,p_len,line,r_err_str);
Error err = _parse_array(a, p_str, index, p_len, line, r_err_str);
if (err)
return err;
value=a;
value = a;
return OK;
} else if (token.type==TK_IDENTIFIER) {
} else if (token.type == TK_IDENTIFIER) {
String id = token.value;
if (id=="true")
value=true;
else if (id=="false")
value=false;
else if (id=="null")
value=Variant();
if (id == "true")
value = true;
else if (id == "false")
value = false;
else if (id == "null")
value = Variant();
else {
r_err_str="Expected 'true','false' or 'null', got '"+id+"'.";
r_err_str = "Expected 'true','false' or 'null', got '" + id + "'.";
return ERR_PARSE_ERROR;
}
return OK;
} else if (token.type==TK_NUMBER) {
} else if (token.type == TK_NUMBER) {
value=token.value;
value = token.value;
return OK;
} else if (token.type==TK_STRING) {
} else if (token.type == TK_STRING) {
value=token.value;
value = token.value;
return OK;
} else {
r_err_str="Expected value, got "+String(tk_name[token.type])+".";
r_err_str = "Expected value, got " + String(tk_name[token.type]) + ".";
return ERR_PARSE_ERROR;
}
return ERR_PARSE_ERROR;
}
Error JSON::_parse_array(Array &array,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str) {
Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
Token token;
bool need_comma=false;
bool need_comma = false;
while (index < p_len) {
while(index<p_len) {
Error err = _get_token(p_str,index,p_len,token,line,r_err_str);
if (err!=OK)
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK)
return err;
if (token.type==TK_BRACKET_CLOSE) {
if (token.type == TK_BRACKET_CLOSE) {
return OK;
}
if (need_comma) {
if (token.type!=TK_COMMA) {
if (token.type != TK_COMMA) {
r_err_str="Expected ','";
r_err_str = "Expected ','";
return ERR_PARSE_ERROR;
} else {
need_comma=false;
need_comma = false;
continue;
}
}
Variant v;
err = _parse_value(v,token,p_str,index,p_len,line,r_err_str);
err = _parse_value(v, token, p_str, index, p_len, line, r_err_str);
if (err)
return err;
array.push_back(v);
need_comma=true;
need_comma = true;
}
return OK;
return ERR_PARSE_ERROR;
}
Error JSON::_parse_object(Dictionary &object,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str) {
Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
bool at_key=true;
bool at_key = true;
String key;
Token token;
bool need_comma=false;
while(index<p_len) {
bool need_comma = false;
while (index < p_len) {
if (at_key) {
Error err = _get_token(p_str,index,p_len,token,line,r_err_str);
if (err!=OK)
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK)
return err;
if (token.type==TK_CURLY_BRACKET_CLOSE) {
if (token.type == TK_CURLY_BRACKET_CLOSE) {
return OK;
}
if (need_comma) {
if (token.type!=TK_COMMA) {
if (token.type != TK_COMMA) {
r_err_str="Expected '}' or ','";
r_err_str = "Expected '}' or ','";
return ERR_PARSE_ERROR;
} else {
need_comma=false;
need_comma = false;
continue;
}
}
if (token.type!=TK_STRING) {
if (token.type != TK_STRING) {
r_err_str="Expected key";
r_err_str = "Expected key";
return ERR_PARSE_ERROR;
}
key=token.value;
err = _get_token(p_str,index,p_len,token,line,r_err_str);
if (err!=OK)
key = token.value;
err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK)
return err;
if (token.type!=TK_COLON) {
if (token.type != TK_COLON) {
r_err_str="Expected ':'";
r_err_str = "Expected ':'";
return ERR_PARSE_ERROR;
}
at_key=false;
at_key = false;
} else {
Error err = _get_token(p_str,index,p_len,token,line,r_err_str);
if (err!=OK)
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
if (err != OK)
return err;
Variant v;
err = _parse_value(v,token,p_str,index,p_len,line,r_err_str);
err = _parse_value(v, token, p_str, index, p_len, line, r_err_str);
if (err)
return err;
object[key]=v;
need_comma=true;
at_key=true;
object[key] = v;
need_comma = true;
at_key = true;
}
}
return OK;
return ERR_PARSE_ERROR;
}
Error JSON::parse(const String& p_json,Dictionary& r_ret,String &r_err_str,int &r_err_line) {
Error JSON::parse(const String &p_json, Dictionary &r_ret, String &r_err_str, int &r_err_line) {
const CharType *str = p_json.ptr();
int idx = 0;
int len = p_json.length();
Token token;
int line=0;
int line = 0;
String aux_key;
Error err = _get_token(str,idx,len,token,line,r_err_str);
Error err = _get_token(str, idx, len, token, line, r_err_str);
if (err)
return err;
if (token.type!=TK_CURLY_BRACKET_OPEN) {
if (token.type != TK_CURLY_BRACKET_OPEN) {
r_err_str="Expected '{'";
r_err_str = "Expected '{'";
return ERR_PARSE_ERROR;
}
return _parse_object(r_ret,str,idx,len,r_err_line,r_err_str);
return _parse_object(r_ret, str, idx, len, r_err_line, r_err_str);
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,11 +30,8 @@
#ifndef JSON_H
#define JSON_H
#include "variant.h"
class JSON {
enum TokenType {
@@ -64,18 +62,18 @@ class JSON {
Variant value;
};
static const char * tk_name[TK_MAX];
static const char *tk_name[TK_MAX];
static String _print_var(const Variant& p_var);
static String _print_var(const Variant &p_var);
static Error _get_token(const CharType *p_str,int &index, int p_len,Token& r_token,int &line,String &r_err_str);
static Error _parse_value(Variant &value,Token& token,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str);
static Error _parse_array(Array &array,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str);
static Error _parse_object(Dictionary &object,const CharType *p_str,int &index, int p_len,int &line,String &r_err_str);
static Error _get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str);
static Error _parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str);
static Error _parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str);
static Error _parse_object(Dictionary &object, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str);
public:
static String print(const Dictionary& p_dict);
static Error parse(const String& p_json,Dictionary& r_ret,String &r_err_str,int &r_err_line);
static String print(const Dictionary &p_dict);
static Error parse(const String &p_json, Dictionary &r_ret, String &r_err_str, int &r_err_line);
};
#endif // JSON_H

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -38,7 +39,6 @@
* in an endian independent way
*/
union MarshallFloat {
uint32_t i; ///< int
@@ -53,41 +53,44 @@ union MarshallDouble {
static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
for (int i=0;i<2;i++) {
for (int i = 0; i < 2; i++) {
*p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8;
*p_arr = p_uint & 0xFF;
p_arr++;
p_uint >>= 8;
}
return sizeof( uint16_t );
return sizeof(uint16_t);
}
static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
for (int i=0;i<4;i++) {
for (int i = 0; i < 4; i++) {
*p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8;
*p_arr = p_uint & 0xFF;
p_arr++;
p_uint >>= 8;
}
return sizeof( uint32_t );
return sizeof(uint32_t);
}
static inline unsigned int encode_float(float p_float, uint8_t *p_arr) {
MarshallFloat mf;
mf.f=p_float;
encode_uint32( mf.i, p_arr );
mf.f = p_float;
encode_uint32(mf.i, p_arr);
return sizeof( uint32_t );
return sizeof(uint32_t);
}
static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
for (int i=0;i<8;i++) {
for (int i = 0; i < 8; i++) {
*p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8;
*p_arr = p_uint & 0xFF;
p_arr++;
p_uint >>= 8;
}
return sizeof(uint64_t);
@@ -96,23 +99,21 @@ static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
static inline unsigned int encode_double(double p_double, uint8_t *p_arr) {
MarshallDouble md;
md.d=p_double;
encode_uint64( md.l, p_arr );
md.d = p_double;
encode_uint64(md.l, p_arr);
return sizeof(uint64_t);
}
static inline int encode_cstring(const char *p_string, uint8_t *p_data) {
static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
int len=0;
int len = 0;
while (*p_string) {
if (p_data) {
*p_data=(uint8_t)*p_string;
*p_data = (uint8_t)*p_string;
p_data++;
}
p_string++;
@@ -120,18 +121,18 @@ static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
};
if (p_data) *p_data = 0;
return len+1;
return len + 1;
}
static inline uint16_t decode_uint16(const uint8_t *p_arr) {
uint16_t u=0;
uint16_t u = 0;
for (int i=0;i<2;i++) {
for (int i = 0; i < 2; i++) {
uint16_t b = *p_arr;
b<<=(i*8);
u|=b;
b <<= (i * 8);
u |= b;
p_arr++;
}
@@ -140,13 +141,13 @@ static inline uint16_t decode_uint16(const uint8_t *p_arr) {
static inline uint32_t decode_uint32(const uint8_t *p_arr) {
uint32_t u=0;
uint32_t u = 0;
for (int i=0;i<4;i++) {
for (int i = 0; i < 4; i++) {
uint32_t b = *p_arr;
b<<=(i*8);
u|=b;
b <<= (i * 8);
u |= b;
p_arr++;
}
@@ -162,13 +163,13 @@ static inline float decode_float(const uint8_t *p_arr) {
static inline uint64_t decode_uint64(const uint8_t *p_arr) {
uint64_t u=0;
uint64_t u = 0;
for (int i=0;i<8;i++) {
for (int i = 0; i < 8; i++) {
uint64_t b = (*p_arr)&0xFF;
b<<=(i*8);
u|=b;
uint64_t b = (*p_arr) & 0xFF;
b <<= (i * 8);
u |= b;
p_arr++;
}
@@ -178,13 +179,11 @@ static inline uint64_t decode_uint64(const uint8_t *p_arr) {
static inline double decode_double(const uint8_t *p_arr) {
MarshallDouble md;
md.l = decode_uint64( p_arr );
md.l = decode_uint64(p_arr);
return md.d;
}
Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *r_len=NULL);
Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len);
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = NULL);
Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len);
#endif

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -28,77 +29,71 @@
/*************************************************************************/
#include "packet_peer.h"
#include "io/marshalls.h"
#include "globals.h"
#include "io/marshalls.h"
/* helpers / binders */
PacketPeer::PacketPeer() {
last_get_error=OK;
last_get_error = OK;
}
Error PacketPeer::get_packet_buffer(DVector<uint8_t> &r_buffer) const {
const uint8_t *buffer;
int buffer_size;
Error err = get_packet(&buffer,buffer_size);
Error err = get_packet(&buffer, buffer_size);
if (err)
return err;
r_buffer.resize(buffer_size);
if (buffer_size==0)
if (buffer_size == 0)
return OK;
DVector<uint8_t>::Write w = r_buffer.write();
for(int i=0;i<buffer_size;i++)
w[i]=buffer[i];
for (int i = 0; i < buffer_size; i++)
w[i] = buffer[i];
return OK;
}
Error PacketPeer::put_packet_buffer(const DVector<uint8_t> &p_buffer) {
int len = p_buffer.size();
if (len==0)
if (len == 0)
return OK;
DVector<uint8_t>::Read r = p_buffer.read();
return put_packet(&r[0],len);
return put_packet(&r[0], len);
}
Error PacketPeer::get_var(Variant &r_variant) const {
const uint8_t *buffer;
int buffer_size;
Error err = get_packet(&buffer,buffer_size);
Error err = get_packet(&buffer, buffer_size);
if (err)
return err;
return decode_variant(r_variant,buffer,buffer_size);
return decode_variant(r_variant, buffer, buffer_size);
}
Error PacketPeer::put_var(const Variant& p_packet) {
Error PacketPeer::put_var(const Variant &p_packet) {
int len;
Error err = encode_variant(p_packet,NULL,len); // compute len first
Error err = encode_variant(p_packet, NULL, len); // compute len first
if (err)
return err;
if (len==0)
if (len == 0)
return OK;
uint8_t *buf = (uint8_t*)alloca(len);
ERR_FAIL_COND_V(!buf,ERR_OUT_OF_MEMORY);
err = encode_variant(p_packet,buf,len);
uint8_t *buf = (uint8_t *)alloca(len);
ERR_FAIL_COND_V(!buf, ERR_OUT_OF_MEMORY);
err = encode_variant(p_packet, buf, len);
ERR_FAIL_COND_V(err, err);
return put_packet(buf, len);
}
Variant PacketPeer::_bnd_get_var() const {
@@ -108,13 +103,13 @@ Variant PacketPeer::_bnd_get_var() const {
return var;
};
Error PacketPeer::_put_packet(const DVector<uint8_t> &p_buffer) {
Error PacketPeer::_put_packet(const DVector<uint8_t> &p_buffer) {
return put_packet_buffer(p_buffer);
}
DVector<uint8_t> PacketPeer::_get_packet() const {
DVector<uint8_t> raw;
last_get_error=get_packet_buffer(raw);
last_get_error = get_packet_buffer(raw);
return raw;
}
@@ -123,20 +118,18 @@ Error PacketPeer::_get_packet_error() const {
return last_get_error;
}
void PacketPeer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_var:Variant"),&PacketPeer::_bnd_get_var);
ObjectTypeDB::bind_method(_MD("put_var", "var:Variant"),&PacketPeer::put_var);
ObjectTypeDB::bind_method(_MD("get_packet"),&PacketPeer::_get_packet);
ObjectTypeDB::bind_method(_MD("put_packet:Error", "buffer"),&PacketPeer::_put_packet);
ObjectTypeDB::bind_method(_MD("get_packet_error:Error"),&PacketPeer::_get_packet_error);
ObjectTypeDB::bind_method(_MD("get_available_packet_count"),&PacketPeer::get_available_packet_count);
ObjectTypeDB::bind_method(_MD("get_var:Variant"), &PacketPeer::_bnd_get_var);
ObjectTypeDB::bind_method(_MD("put_var", "var:Variant"), &PacketPeer::put_var);
ObjectTypeDB::bind_method(_MD("get_packet"), &PacketPeer::_get_packet);
ObjectTypeDB::bind_method(_MD("put_packet:Error", "buffer"), &PacketPeer::_put_packet);
ObjectTypeDB::bind_method(_MD("get_packet_error:Error"), &PacketPeer::_get_packet_error);
ObjectTypeDB::bind_method(_MD("get_available_packet_count"), &PacketPeer::get_available_packet_count);
};
/***************/
void PacketPeerStream::_set_stream_peer(REF p_peer) {
ERR_FAIL_COND(p_peer.is_null());
@@ -145,22 +138,22 @@ void PacketPeerStream::_set_stream_peer(REF p_peer) {
void PacketPeerStream::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_stream_peer","peer:StreamPeer"),&PacketPeerStream::_set_stream_peer);
ObjectTypeDB::bind_method(_MD("set_stream_peer", "peer:StreamPeer"), &PacketPeerStream::_set_stream_peer);
}
Error PacketPeerStream::_poll_buffer() const {
ERR_FAIL_COND_V(peer.is_null(),ERR_UNCONFIGURED);
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
int read = 0;
Error err = peer->get_partial_data(&temp_buffer[0], ring_buffer.space_left(), read);
if (err)
return err;
if (read==0)
if (read == 0)
return OK;
int w = ring_buffer.write(&temp_buffer[0],read);
ERR_FAIL_COND_V(w!=read,ERR_BUG);
int w = ring_buffer.write(&temp_buffer[0], read);
ERR_FAIL_COND_V(w != read, ERR_BUG);
return OK;
}
@@ -171,73 +164,71 @@ int PacketPeerStream::get_available_packet_count() const {
uint32_t remaining = ring_buffer.data_left();
int ofs=0;
int count=0;
int ofs = 0;
int count = 0;
while(remaining>=4) {
while (remaining >= 4) {
uint8_t lbuf[4];
ring_buffer.copy(lbuf,ofs,4);
ring_buffer.copy(lbuf, ofs, 4);
uint32_t len = decode_uint32(lbuf);
remaining-=4;
ofs+=4;
if (len>remaining)
remaining -= 4;
ofs += 4;
if (len > remaining)
break;
remaining-=len;
ofs+=len;
remaining -= len;
ofs += len;
count++;
}
return count;
}
Error PacketPeerStream::get_packet(const uint8_t **r_buffer,int &r_buffer_size) const {
Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size) const {
ERR_FAIL_COND_V(peer.is_null(),ERR_UNCONFIGURED);
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
_poll_buffer();
int remaining = ring_buffer.data_left();
ERR_FAIL_COND_V(remaining<4,ERR_UNAVAILABLE);
ERR_FAIL_COND_V(remaining < 4, ERR_UNAVAILABLE);
uint8_t lbuf[4];
ring_buffer.copy(lbuf,0,4);
remaining-=4;
ring_buffer.copy(lbuf, 0, 4);
remaining -= 4;
uint32_t len = decode_uint32(lbuf);
ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE);
ERR_FAIL_COND_V(remaining < (int)len, ERR_UNAVAILABLE);
ring_buffer.read(lbuf,4); //get rid of first 4 bytes
ring_buffer.read(&temp_buffer[0],len); // read packet
ring_buffer.read(lbuf, 4); //get rid of first 4 bytes
ring_buffer.read(&temp_buffer[0], len); // read packet
*r_buffer=&temp_buffer[0];
r_buffer_size=len;
*r_buffer = &temp_buffer[0];
r_buffer_size = len;
return OK;
}
Error PacketPeerStream::put_packet(const uint8_t *p_buffer,int p_buffer_size) {
Error PacketPeerStream::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
ERR_FAIL_COND_V(peer.is_null(),ERR_UNCONFIGURED);
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
Error err = _poll_buffer(); //won't hurt to poll here too
if (err)
return err;
if (p_buffer_size==0)
if (p_buffer_size == 0)
return OK;
ERR_FAIL_COND_V( p_buffer_size<0, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V( p_buffer_size+4 > temp_buffer.size(), ERR_INVALID_PARAMETER );
ERR_FAIL_COND_V(p_buffer_size < 0, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_buffer_size + 4 > temp_buffer.size(), ERR_INVALID_PARAMETER);
encode_uint32(p_buffer_size,&temp_buffer[0]);
uint8_t *dst=&temp_buffer[4];
for(int i=0;i<p_buffer_size;i++)
dst[i]=p_buffer[i];
encode_uint32(p_buffer_size, &temp_buffer[0]);
uint8_t *dst = &temp_buffer[4];
for (int i = 0; i < p_buffer_size; i++)
dst[i] = p_buffer[i];
return peer->put_data(&temp_buffer[0],p_buffer_size+4);
return peer->put_data(&temp_buffer[0], p_buffer_size + 4);
}
int PacketPeerStream::get_max_packet_size() const {
return temp_buffer.size();
}
@@ -249,7 +240,7 @@ void PacketPeerStream::set_stream_peer(const Ref<StreamPeer> &p_peer) {
ring_buffer.advance_read(ring_buffer.data_left()); // reset the ring buffer
};
peer=p_peer;
peer = p_peer;
}
void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
@@ -257,18 +248,14 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
//warning may lose packets
ERR_EXPLAIN("Buffer in use, resizing would cause loss of data");
ERR_FAIL_COND(ring_buffer.data_left());
ring_buffer.resize(nearest_shift(p_max_size+4));
temp_buffer.resize(nearest_power_of_2(p_max_size+4));
ring_buffer.resize(nearest_shift(p_max_size + 4));
temp_buffer.resize(nearest_power_of_2(p_max_size + 4));
}
PacketPeerStream::PacketPeerStream() {
int rbsize=GLOBAL_DEF( "core/packet_stream_peer_max_buffer_po2",(16));
int rbsize = GLOBAL_DEF("core/packet_stream_peer_max_buffer_po2", (16));
ring_buffer.resize(rbsize);
temp_buffer.resize(1<<rbsize);
temp_buffer.resize(1 << rbsize);
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,33 +30,30 @@
#ifndef PACKET_PEER_H
#define PACKET_PEER_H
#include "object.h"
#include "io/stream_peer.h"
#include "object.h"
#include "ring_buffer.h"
class PacketPeer : public Reference {
OBJ_TYPE( PacketPeer, Reference );
OBJ_TYPE(PacketPeer, Reference);
Variant _bnd_get_var() const;
void _bnd_put_var(const Variant& p_var);
void _bnd_put_var(const Variant &p_var);
static void _bind_methods();
Error _put_packet(const DVector<uint8_t> &p_buffer);
DVector<uint8_t> _get_packet() const;
Error _get_packet_error() const;
mutable Error last_get_error;
public:
virtual int get_available_packet_count() const = 0;
virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) const = 0; ///< buffer is GONE after next get_packet
virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) = 0;
virtual int get_available_packet_count() const=0;
virtual Error get_packet(const uint8_t **r_buffer,int &r_buffer_size) const=0; ///< buffer is GONE after next get_packet
virtual Error put_packet(const uint8_t *p_buffer,int p_buffer_size)=0;
virtual int get_max_packet_size() const=0;
virtual int get_max_packet_size() const = 0;
/* helpers / binders */
@@ -63,15 +61,15 @@ public:
virtual Error put_packet_buffer(const DVector<uint8_t> &p_buffer);
virtual Error get_var(Variant &r_variant) const;
virtual Error put_var(const Variant& p_packet);
virtual Error put_var(const Variant &p_packet);
PacketPeer();
~PacketPeer(){}
~PacketPeer() {}
};
class PacketPeerStream : public PacketPeer {
OBJ_TYPE(PacketPeerStream,PacketPeer);
OBJ_TYPE(PacketPeerStream, PacketPeer);
//the way the buffers work sucks, will change later
@@ -80,23 +78,21 @@ class PacketPeerStream : public PacketPeer {
mutable Vector<uint8_t> temp_buffer;
Error _poll_buffer() const;
protected:
protected:
void _set_stream_peer(REF p_peer);
static void _bind_methods();
public:
public:
virtual int get_available_packet_count() const;
virtual Error get_packet(const uint8_t **r_buffer,int &r_buffer_size) const;
virtual Error put_packet(const uint8_t *p_buffer,int p_buffer_size);
virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) const;
virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size);
virtual int get_max_packet_size() const;
void set_stream_peer(const Ref<StreamPeer>& p_peer);
void set_stream_peer(const Ref<StreamPeer> &p_peer);
void set_input_buffer_max_size(int p_max_size);
PacketPeerStream();
};
#endif // PACKET_STREAM_H

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,47 +30,38 @@
#include "packet_peer_udp.h"
#include "io/ip.h"
PacketPeerUDP* (*PacketPeerUDP::_create)()=NULL;
int PacketPeerUDP::_get_packet_address() const {
IP_Address ip = get_packet_address();
return ip.host;
}
PacketPeerUDP *(*PacketPeerUDP::_create)() = NULL;
String PacketPeerUDP::_get_packet_ip() const {
return get_packet_address();
}
Error PacketPeerUDP::_set_send_address(const String& p_address,int p_port) {
Error PacketPeerUDP::_set_send_address(const String &p_address, int p_port) {
IP_Address ip;
if (p_address.is_valid_ip_address()) {
ip=p_address;
ip = p_address;
} else {
ip=IP::get_singleton()->resolve_hostname(p_address);
if (ip==IP_Address())
ip = IP::get_singleton()->resolve_hostname(p_address);
if (!ip.is_valid())
return ERR_CANT_RESOLVE;
}
set_send_address(ip,p_port);
set_send_address(ip, p_port);
return OK;
}
void PacketPeerUDP::_bind_methods() {
ObjectTypeDB::bind_method(_MD("listen:Error","port","recv_buf_size"),&PacketPeerUDP::listen,DEFVAL(65536));
ObjectTypeDB::bind_method(_MD("close"),&PacketPeerUDP::close);
ObjectTypeDB::bind_method(_MD("wait:Error"),&PacketPeerUDP::wait);
ObjectTypeDB::bind_method(_MD("is_listening"),&PacketPeerUDP::is_listening);
ObjectTypeDB::bind_method(_MD("get_packet_ip"),&PacketPeerUDP::_get_packet_ip);
ObjectTypeDB::bind_method(_MD("get_packet_address"),&PacketPeerUDP::_get_packet_address);
ObjectTypeDB::bind_method(_MD("get_packet_port"),&PacketPeerUDP::get_packet_port);
ObjectTypeDB::bind_method(_MD("set_send_address","host","port"),&PacketPeerUDP::_set_send_address);
ObjectTypeDB::bind_method(_MD("listen:Error", "port", "bind_address", "recv_buf_size"), &PacketPeerUDP::listen, DEFVAL("*"), DEFVAL(65536));
ObjectTypeDB::bind_method(_MD("close"), &PacketPeerUDP::close);
ObjectTypeDB::bind_method(_MD("wait:Error"), &PacketPeerUDP::wait);
ObjectTypeDB::bind_method(_MD("is_listening"), &PacketPeerUDP::is_listening);
ObjectTypeDB::bind_method(_MD("get_packet_ip"), &PacketPeerUDP::_get_packet_ip);
//ObjectTypeDB::bind_method(_MD("get_packet_address"),&PacketPeerUDP::_get_packet_address);
ObjectTypeDB::bind_method(_MD("get_packet_port"), &PacketPeerUDP::get_packet_port);
ObjectTypeDB::bind_method(_MD("set_send_address", "host", "port"), &PacketPeerUDP::_set_send_address);
}
Ref<PacketPeerUDP> PacketPeerUDP::create_ref() {
@@ -79,13 +71,12 @@ Ref<PacketPeerUDP> PacketPeerUDP::create_ref() {
return Ref<PacketPeerUDP>(_create());
}
PacketPeerUDP* PacketPeerUDP::create() {
PacketPeerUDP *PacketPeerUDP::create() {
if (!_create)
return NULL;
return _create();
}
PacketPeerUDP::PacketPeerUDP()
{
PacketPeerUDP::PacketPeerUDP() {
}

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -29,35 +30,31 @@
#ifndef PACKET_PEER_UDP_H
#define PACKET_PEER_UDP_H
#include "io/ip.h"
#include "io/packet_peer.h"
class PacketPeerUDP : public PacketPeer {
OBJ_TYPE(PacketPeerUDP,PacketPeer);
OBJ_TYPE(PacketPeerUDP, PacketPeer);
protected:
static PacketPeerUDP* (*_create)();
static PacketPeerUDP *(*_create)();
static void _bind_methods();
int _get_packet_address() const;
String _get_packet_ip() const;
virtual Error _set_send_address(const String& p_address,int p_port);
Error _set_send_address(const String &p_address, int p_port);
public:
virtual Error listen(int p_port,int p_recv_buffer_size=65536)=0;
virtual void close()=0;
virtual Error wait()=0;
virtual bool is_listening() const=0;
virtual IP_Address get_packet_address() const=0;
virtual int get_packet_port() const=0;
virtual void set_send_address(const IP_Address& p_address,int p_port)=0;
virtual Error listen(int p_port, IP_Address p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536) = 0;
virtual void close() = 0;
virtual Error wait() = 0;
virtual bool is_listening() const = 0;
virtual IP_Address get_packet_address() const = 0;
virtual int get_packet_port() const = 0;
virtual void set_send_address(const IP_Address &p_address, int p_port) = 0;
static Ref<PacketPeerUDP> create_ref();
static PacketPeerUDP* create();
static PacketPeerUDP *create();
PacketPeerUDP();
};

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -42,9 +43,9 @@ static uint64_t _align(uint64_t p_n, int p_alignment) {
return p_n + (p_alignment - rest);
};
static void _pad(FileAccess* p_file, int p_bytes) {
static void _pad(FileAccess *p_file, int p_bytes) {
for (int i=0; i<p_bytes; i++) {
for (int i = 0; i < p_bytes; i++) {
p_file->store_8(0);
};
@@ -52,13 +53,12 @@ static void _pad(FileAccess* p_file, int p_bytes) {
void PCKPacker::_bind_methods() {
ObjectTypeDB::bind_method(_MD("pck_start","pck_name","alignment"),&PCKPacker::pck_start);
ObjectTypeDB::bind_method(_MD("add_file","pck_path","source_path"),&PCKPacker::add_file);
ObjectTypeDB::bind_method(_MD("flush","verbose"),&PCKPacker::flush);
ObjectTypeDB::bind_method(_MD("pck_start", "pck_name", "alignment"), &PCKPacker::pck_start);
ObjectTypeDB::bind_method(_MD("add_file", "pck_path", "source_path"), &PCKPacker::add_file);
ObjectTypeDB::bind_method(_MD("flush", "verbose"), &PCKPacker::flush);
};
Error PCKPacker::pck_start(const String& p_file, int p_alignment) {
Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
file = FileAccess::open(p_file, FileAccess::WRITE);
if (file == NULL) {
@@ -74,7 +74,7 @@ Error PCKPacker::pck_start(const String& p_file, int p_alignment) {
file->store_32(0); // # minor
file->store_32(0); // # revision
for (int i=0; i<16; i++) {
for (int i = 0; i < 16; i++) {
file->store_32(0); // reserved
};
@@ -84,9 +84,9 @@ Error PCKPacker::pck_start(const String& p_file, int p_alignment) {
return OK;
};
Error PCKPacker::add_file(const String& p_file, const String& p_src) {
Error PCKPacker::add_file(const String &p_file, const String &p_src) {
FileAccess* f = FileAccess::open(p_src, FileAccess::READ);
FileAccess *f = FileAccess::open(p_src, FileAccess::READ);
if (!f) {
return ERR_FILE_CANT_OPEN;
};
@@ -116,7 +116,7 @@ Error PCKPacker::flush(bool p_verbose) {
file->store_32(files.size());
for (int i=0; i<files.size(); i++) {
for (int i = 0; i < files.size(); i++) {
file->store_pascal_string(files[i].path);
files[i].offset_offset = file->get_pos();
@@ -130,7 +130,6 @@ Error PCKPacker::flush(bool p_verbose) {
file->store_32(0);
};
uint64_t ofs = file->get_pos();
ofs = _align(ofs, alignment);
@@ -140,9 +139,9 @@ Error PCKPacker::flush(bool p_verbose) {
uint8_t *buf = memnew_arr(uint8_t, buf_max);
int count = 0;
for (int i=0; i<files.size(); i++) {
for (int i = 0; i < files.size(); i++) {
FileAccess* src = FileAccess::open(files[i].src_path, FileAccess::READ);
FileAccess *src = FileAccess::open(files[i].src_path, FileAccess::READ);
uint64_t to_write = files[i].size;
while (to_write > 0) {

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -34,7 +35,7 @@ class PCKPacker : public Reference {
OBJ_TYPE(PCKPacker, Reference);
FileAccess* file;
FileAccess *file;
int alignment;
static void _bind_methods();
@@ -49,11 +50,10 @@ class PCKPacker : public Reference {
Vector<File> files;
public:
Error pck_start(const String& p_file, int p_alignment);
Error add_file(const String& p_file, const String& p_src);
Error pck_start(const String &p_file, int p_alignment);
Error add_file(const String &p_file, const String &p_src);
Error flush(bool p_verbose = false);
PCKPacker();
~PCKPacker();
};

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -33,7 +34,6 @@
#include "io/resource_saver.h"
#include "os/file_access.h"
class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
String local_path;
@@ -43,7 +43,6 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
FileAccess *f;
bool endian_swap;
bool use_real64;
uint64_t importmd_ofs;
@@ -71,59 +70,54 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
String get_unicode_string();
void _advance_padding(uint32_t p_len);
Map<String,String> remaps;
Map<String, String> remaps;
Error error;
int stage;
friend class ResourceFormatLoaderBinary;
friend class ResourceFormatLoaderBinary;
Error parse_variant(Variant& r_v);
Error parse_variant(Variant &r_v, bool p_for_export_data = false);
public:
virtual void set_local_path(const String& p_local_path);
virtual void set_local_path(const String &p_local_path);
virtual Ref<Resource> get_resource();
virtual Error poll();
virtual int get_stage() const;
virtual int get_stage_count() const;
void set_remaps(const Map<String,String>& p_remaps) { remaps=p_remaps; }
void set_remaps(const Map<String, String> &p_remaps) { remaps = p_remaps; }
void open(FileAccess *p_f);
String recognize(FileAccess *p_f);
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
Error get_export_data(ExportData &r_export_data);
ResourceInteractiveLoaderBinary();
~ResourceInteractiveLoaderBinary();
};
class ResourceFormatLoaderBinary : public ResourceFormatLoader {
public:
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const;
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata> &r_var) const;
virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
virtual Error get_export_data(const String &p_path, ExportData &r_export_data);
static ResourceFormatLoaderBinary *singleton;
ResourceFormatLoaderBinary() { singleton = this; }
};
class ResourceFormatSaverBinaryInstance {
class ResourceFormatSaverBinaryInstance {
String local_path;
bool relative_paths;
bool bundle_resources;
bool skip_editor;
@@ -133,19 +127,16 @@ class ResourceFormatSaverBinaryInstance {
FileAccess *f;
String magic;
Set<RES> resource_set;
Map<StringName,int> string_map;
Map<StringName, int> string_map;
Vector<StringName> strings;
Map<RES,int> external_resources;
Map<RES, int> external_resources;
List<RES> saved_resources;
struct Property {
int name_idx;
Variant value;
PropertyInfo pi;
};
struct ResourceData {
@@ -154,36 +145,25 @@ class ResourceFormatSaverBinaryInstance {
List<Property> properties;
};
void _pad_buffer(int p_bytes);
void write_variant(const Variant& p_property,const PropertyInfo& p_hint=PropertyInfo());
void _find_resources(const Variant& p_variant,bool p_main=false);
void save_unicode_string(const String& p_string);
int get_string_index(const String& p_string);
void write_variant(const Variant &p_property, const PropertyInfo &p_hint = PropertyInfo());
void _find_resources(const Variant &p_variant, bool p_main = false);
void save_unicode_string(const String &p_string);
int get_string_index(const String &p_string);
public:
Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
};
class ResourceFormatSaverBinary : public ResourceFormatSaver {
class ResourceFormatSaverBinary : public ResourceFormatSaver {
public:
static ResourceFormatSaverBinary* singleton;
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
virtual bool recognize(const RES& p_resource) const;
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
static ResourceFormatSaverBinary *singleton;
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual bool recognize(const RES &p_resource) const;
virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
ResourceFormatSaverBinary();
};
#endif // RESOURCE_FORMAT_BINARY_H

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 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 */
@@ -33,8 +34,6 @@
#include "io/resource_saver.h"
#include "os/file_access.h"
class ResourceInteractiveLoaderXML : public ResourceInteractiveLoader {
String local_path;
@@ -45,22 +44,19 @@ class ResourceInteractiveLoaderXML : public ResourceInteractiveLoader {
struct Tag {
String name;
HashMap<String,String> args;
HashMap<String, String> args;
};
_FORCE_INLINE_ Error _parse_array_element(Vector<char> &buff,bool p_number_only,FileAccess *f,bool *end);
_FORCE_INLINE_ Error _parse_array_element(Vector<char> &buff, bool p_number_only, FileAccess *f, bool *end);
struct ExtResource {
String path;
String type;
};
Map<String, String> remaps;
Map<String,String> remaps;
Map<int,ExtResource> ext_resources;
Map<int, ExtResource> ext_resources;
int resources_total;
int resource_current;
@@ -70,24 +66,23 @@ class ResourceInteractiveLoaderXML : public ResourceInteractiveLoader {
uint8_t get_char() const;
int get_current_line() const;
friend class ResourceFormatLoaderXML;
friend class ResourceFormatLoaderXML;
List<Tag> tag_stack;
List<RES> resource_cache;
Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true,List<String> *r_order=NULL);
Error close_tag(const String& p_name);
_FORCE_INLINE_ void unquote(String& p_str);
Tag *parse_tag(bool *r_exit = NULL, bool p_printerr = true, List<String> *r_order = NULL);
Error close_tag(const String &p_name);
_FORCE_INLINE_ void unquote(String &p_str);
Error goto_end_of_tag();
Error parse_property_data(String &r_data);
Error parse_property(Variant& r_v, String &r_name);
Error parse_property(Variant &r_v, String &r_name, bool p_for_export_data = false);
Error error;
RES resource;
public:
virtual void set_local_path(const String& p_local_path);
virtual void set_local_path(const String &p_local_path);
virtual Ref<Resource> get_resource();
virtual Error poll();
virtual int get_stage() const;
@@ -96,37 +91,34 @@ public:
void open(FileAccess *p_f);
String recognize(FileAccess *p_f);
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
Error rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map);
Error rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map);
Error get_export_data(FileAccess *p_f, ExportData &r_export_data);
~ResourceInteractiveLoaderXML();
};
class ResourceFormatLoaderXML : public ResourceFormatLoader {
public:
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
static ResourceFormatLoaderXML *singleton;
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, Error *r_error = NULL);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
virtual Error get_export_data(const String &p_path, ExportData &r_export_data);
ResourceFormatLoaderXML() { singleton = this; }
};
////////////////////////////////////////////////////////////////////////////////////////////
class ResourceFormatSaverXMLInstance {
class ResourceFormatSaverXMLInstance {
String local_path;
bool takeover_paths;
bool relative_paths;
bool bundle_resources;
@@ -135,36 +127,30 @@ class ResourceFormatSaverXMLInstance {
int depth;
Set<RES> resource_set;
List<RES> saved_resources;
Map<RES,int> external_resources;
Map<RES, int> external_resources;
void enter_tag(const char* p_tag,const String& p_args=String());
void exit_tag(const char* p_tag);
void enter_tag(const char *p_tag, const String &p_args = String());
void exit_tag(const char *p_tag);
void _find_resources(const Variant& p_variant,bool p_main=false);
void write_property(const String& p_name,const Variant& p_property,bool *r_ok=NULL);
void escape(String& p_str);
void write_tabs(int p_diff=0);
void write_string(String p_str,bool p_escape=true);
void _find_resources(const Variant &p_variant, bool p_main = false);
void write_property(const String &p_name, const Variant &p_property, bool *r_ok = NULL);
void escape(String &p_str);
void write_tabs(int p_diff = 0);
void write_string(String p_str, bool p_escape = true);
public:
Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
};
class ResourceFormatSaverXML : public ResourceFormatSaver {
public:
static ResourceFormatSaverXML* singleton;
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
virtual bool recognize(const RES& p_resource) const;
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
static ResourceFormatSaverXML *singleton;
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual bool recognize(const RES &p_resource) const;
virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
ResourceFormatSaverXML();
};
#endif // RESOURCE_FORMAT_XML_H

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