summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gdnative/SCsub6
-rw-r--r--modules/gdnative/gd_native_library_editor.cpp2
-rw-r--r--modules/gdnative/gdnative.cpp375
-rw-r--r--modules/gdnative/gdnative.h111
-rw-r--r--modules/gdnative/gdnative/array.cpp3
-rw-r--r--modules/gdnative/gdnative/basis.cpp2
-rw-r--r--modules/gdnative/gdnative/color.cpp2
-rw-r--r--modules/gdnative/gdnative/dictionary.cpp2
-rw-r--r--modules/gdnative/gdnative/gdnative.cpp49
-rw-r--r--modules/gdnative/gdnative/node_path.cpp2
-rw-r--r--modules/gdnative/gdnative/plane.cpp2
-rw-r--r--modules/gdnative/gdnative/pool_arrays.cpp3
-rw-r--r--modules/gdnative/gdnative/quat.cpp2
-rw-r--r--modules/gdnative/gdnative/rect2.cpp2
-rw-r--r--modules/gdnative/gdnative/rect3.cpp2
-rw-r--r--modules/gdnative/gdnative/rid.cpp2
-rw-r--r--modules/gdnative/gdnative/string.cpp3
-rw-r--r--modules/gdnative/gdnative/string_name.cpp3
-rw-r--r--modules/gdnative/gdnative/transform.cpp2
-rw-r--r--modules/gdnative/gdnative/transform2d.cpp2
-rw-r--r--modules/gdnative/gdnative/variant.cpp2
-rw-r--r--modules/gdnative/gdnative/vector2.cpp2
-rw-r--r--modules/gdnative/gdnative/vector3.cpp2
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h2
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp46
-rw-r--r--modules/gdnative/nativescript/nativescript.h8
-rw-r--r--modules/gdnative/register_types.cpp18
-rw-r--r--modules/gdscript/gd_editor.cpp2
-rw-r--r--modules/ogg/config.py3
-rw-r--r--modules/opus/SCsub11
-rw-r--r--modules/opus/config.py3
-rw-r--r--modules/opus/stub/register_types.cpp36
-rw-r--r--modules/opus/stub/register_types.h31
-rw-r--r--modules/regex/regex.cpp16
-rw-r--r--modules/regex/regex.h1
-rw-r--r--modules/theora/config.py3
-rw-r--r--modules/theora/register_types.cpp13
-rw-r--r--modules/theora/resource_importer_theora.cpp89
-rw-r--r--modules/theora/resource_importer_theora.h57
-rw-r--r--modules/theora/video_stream_theora.cpp46
-rw-r--r--modules/theora/video_stream_theora.h16
-rw-r--r--modules/vorbis/SCsub10
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.cpp4
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.h2
-rw-r--r--modules/vorbis/config.py3
-rw-r--r--modules/vorbis/stub/register_types.cpp36
-rw-r--r--modules/vorbis/stub/register_types.h31
-rw-r--r--modules/webm/config.py3
-rw-r--r--modules/webm/libvpx/SCsub4
-rw-r--r--modules/webm/register_types.cpp13
-rw-r--r--modules/webm/resource_importer_webm.cpp95
-rw-r--r--modules/webm/resource_importer_webm.h55
-rw-r--r--modules/webm/video_stream_webm.cpp153
-rw-r--r--modules/webm/video_stream_webm.h23
54 files changed, 931 insertions, 485 deletions
diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub
index 88588417d1..2755930a55 100644
--- a/modules/gdnative/SCsub
+++ b/modules/gdnative/SCsub
@@ -40,11 +40,13 @@ def _build_gdnative_api_struct_header(api):
'\tunsigned int minor;',
'} godot_gdnative_api_version;',
'',
- 'typedef struct godot_gdnative_api_struct {',
+ 'typedef struct godot_gdnative_api_struct godot_gdnative_api_struct;',
+ '',
+ 'struct godot_gdnative_api_struct {',
'\tunsigned int type;',
'\tgodot_gdnative_api_version version;',
'\tconst godot_gdnative_api_struct *next;',
- '} godot_gdnative_api_struct;',
+ '};',
'',
'enum GDNATIVE_API_TYPES {',
'\tGDNATIVE_' + api['core']['type'] + ','
diff --git a/modules/gdnative/gd_native_library_editor.cpp b/modules/gdnative/gd_native_library_editor.cpp
index c37b7f473d..fda5dcdcad 100644
--- a/modules/gdnative/gd_native_library_editor.cpp
+++ b/modules/gdnative/gd_native_library_editor.cpp
@@ -44,7 +44,7 @@ void GDNativeLibraryEditor::_find_gdnative_singletons(EditorFileSystemDirectory
}
Ref<GDNativeLibrary> lib = ResourceLoader::load(p_dir->get_file_path(i));
- if (lib.is_valid() && lib->is_singleton_gdnative()) {
+ if (lib.is_valid() && lib->is_singleton()) {
String path = p_dir->get_file_path(i);
TreeItem *ti = libraries->create_item(libraries->get_root());
ti->set_text(0, path.get_file());
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 832a0cb859..44d6dffc85 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -37,161 +37,56 @@
#include "scene/main/scene_tree.h"
-const String init_symbol = "godot_gdnative_init";
-const String terminate_symbol = "godot_gdnative_terminate";
+const String init_symbol = "gdnative_init";
+const String terminate_symbol = "gdnative_terminate";
+const String default_symbol_prefix = "godot_";
// Defined in gdnative_api_struct.gen.cpp
extern const godot_gdnative_core_api_struct api_struct;
-String GDNativeLibrary::platform_names[NUM_PLATFORMS + 1] = {
- "X11_32bit",
- "X11_64bit",
- "Windows_32bit",
- "Windows_64bit",
- "OSX",
-
- "Android",
-
- "iOS_32bit",
- "iOS_64bit",
-
- "WebAssembly",
-
- ""
-};
-String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS + 1] = {
- "so",
- "so",
- "dll",
- "dll",
- "dylib",
-
- "so",
-
- "dylib",
- "dylib",
-
- "wasm",
-
- ""
-};
-
-GDNativeLibrary::Platform GDNativeLibrary::current_platform =
-#if defined(X11_ENABLED)
- (sizeof(void *) == 8 ? X11_64BIT : X11_32BIT);
-#elif defined(WINDOWS_ENABLED)
- (sizeof(void *) == 8 ? WINDOWS_64BIT : WINDOWS_32BIT);
-#elif defined(OSX_ENABLED)
- OSX;
-#elif defined(IPHONE_ENABLED)
- (sizeof(void *) == 8 ? IOS_64BIT : IOS_32BIT);
-#elif defined(ANDROID_ENABLED)
- ANDROID;
-#elif defined(JAVASCRIPT_ENABLED)
- WASM;
-#else
- NUM_PLATFORMS;
-#endif
-
-GDNativeLibrary::GDNativeLibrary()
- : library_paths(), singleton_gdnative(false) {
-}
+Map<String, Vector<Ref<GDNative> > > *GDNativeLibrary::loaded_libraries = NULL;
-GDNativeLibrary::~GDNativeLibrary() {
-}
-
-void GDNativeLibrary::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_library_path", "platform", "path"), &GDNativeLibrary::set_library_path);
- ClassDB::bind_method(D_METHOD("get_library_path", "platform"), &GDNativeLibrary::get_library_path);
- ClassDB::bind_method(D_METHOD("get_active_library_path"), &GDNativeLibrary::get_active_library_path);
+GDNativeLibrary::GDNativeLibrary() {
+ config_file.instance();
- ClassDB::bind_method(D_METHOD("is_singleton_gdnative"), &GDNativeLibrary::is_singleton_gdnative);
- ClassDB::bind_method(D_METHOD("set_singleton_gdnative", "singleton"), &GDNativeLibrary::set_singleton_gdnative);
+ symbol_prefix = default_symbol_prefix;
- ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton_gdnative"), "set_singleton_gdnative", "is_singleton_gdnative");
-}
-
-bool GDNativeLibrary::_set(const StringName &p_name, const Variant &p_value) {
- String name = p_name;
- if (name.begins_with("platform/")) {
- set_library_path(name.get_slice("/", 1), p_value);
- return true;
- }
- return false;
-}
-
-bool GDNativeLibrary::_get(const StringName &p_name, Variant &r_ret) const {
- String name = p_name;
- if (name.begins_with("platform/")) {
- r_ret = get_library_path(name.get_slice("/", 1));
- return true;
+ if (GDNativeLibrary::loaded_libraries == NULL) {
+ GDNativeLibrary::loaded_libraries = memnew((Map<String, Vector<Ref<GDNative> > >));
}
- return false;
}
-void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
- for (int i = 0; i < NUM_PLATFORMS; i++) {
- p_list->push_back(PropertyInfo(Variant::STRING,
- "platform/" + platform_names[i],
- PROPERTY_HINT_FILE,
- "*." + platform_lib_ext[i]));
- }
+GDNativeLibrary::~GDNativeLibrary() {
}
-void GDNativeLibrary::set_library_path(StringName p_platform, String p_path) {
- int i;
- for (i = 0; i <= NUM_PLATFORMS; i++) {
- if (i == NUM_PLATFORMS) break;
- if (platform_names[i] == p_platform) {
- break;
- }
- }
-
- if (i == NUM_PLATFORMS) {
- ERR_EXPLAIN(String("No such platform: ") + p_platform);
- ERR_FAIL();
- }
+void GDNativeLibrary::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_config_file"), &GDNativeLibrary::get_config_file);
- library_paths[i] = p_path;
-}
+ ClassDB::bind_method(D_METHOD("get_current_library_path"), &GDNativeLibrary::get_current_library_path);
+ ClassDB::bind_method(D_METHOD("get_current_dependencies"), &GDNativeLibrary::get_current_dependencies);
+ ClassDB::bind_method(D_METHOD("is_current_library_statically_linked"), &GDNativeLibrary::is_current_library_statically_linked);
-String GDNativeLibrary::get_library_path(StringName p_platform) const {
- int i;
- for (i = 0; i <= NUM_PLATFORMS; i++) {
- if (i == NUM_PLATFORMS) break;
- if (platform_names[i] == p_platform) {
- break;
- }
- }
+ ClassDB::bind_method(D_METHOD("should_load_once"), &GDNativeLibrary::should_load_once);
+ ClassDB::bind_method(D_METHOD("is_singleton"), &GDNativeLibrary::is_singleton);
+ ClassDB::bind_method(D_METHOD("get_symbol_prefix"), &GDNativeLibrary::get_symbol_prefix);
- if (i == NUM_PLATFORMS) {
- ERR_EXPLAIN(String("No such platform: ") + p_platform);
- ERR_FAIL_V("");
- }
+ ClassDB::bind_method(D_METHOD("set_load_once", "load_once"), &GDNativeLibrary::set_load_once);
+ ClassDB::bind_method(D_METHOD("set_singleton", "singleton"), &GDNativeLibrary::set_singleton);
+ ClassDB::bind_method(D_METHOD("set_symbol_prefix", "symbol_prefix"), &GDNativeLibrary::set_symbol_prefix);
- return library_paths[i];
-}
-
-String GDNativeLibrary::get_active_library_path() const {
- if (GDNativeLibrary::current_platform != NUM_PLATFORMS) {
- return library_paths[GDNativeLibrary::current_platform];
- }
- return "";
+ ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "load_once"), "set_load_once", "should_load_once");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton"), "set_singleton", "is_singleton");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "symbol_prefix"), "set_symbol_prefix", "get_symbol_prefix");
}
GDNative::GDNative() {
native_handle = NULL;
+ initialized = false;
}
GDNative::~GDNative() {
}
-extern "C" void _api_anchor();
-
-void GDNative::_compile_dummy_for_api() {
- _api_anchor();
-}
-
void GDNative::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_library", "library"), &GDNative::set_library);
ClassDB::bind_method(D_METHOD("get_library"), &GDNative::get_library);
@@ -220,8 +115,8 @@ bool GDNative::initialize() {
return false;
}
- String lib_path = library->get_active_library_path();
- if (lib_path.empty()) {
+ String lib_path = library->get_current_library_path();
+ if (lib_path.empty() && !library->is_current_library_statically_linked()) {
ERR_PRINT("No library set for this platform");
return false;
}
@@ -230,16 +125,34 @@ bool GDNative::initialize() {
#else
String path = ProjectSettings::get_singleton()->globalize_path(lib_path);
#endif
+
+ if (library->should_load_once()) {
+ if (GDNativeLibrary::loaded_libraries->has(lib_path)) {
+ // already loaded. Don't load again.
+ // copy some of the stuff instead
+ this->native_handle = (*GDNativeLibrary::loaded_libraries)[lib_path][0]->native_handle;
+ initialized = true;
+ return true;
+ }
+ }
+
Error err = OS::get_singleton()->open_dynamic_library(path, native_handle);
- if (err != OK) {
+ if (err != OK && !library->is_current_library_statically_linked()) {
return false;
}
void *library_init;
- err = get_symbol(init_symbol, library_init);
+
+ // we cheat here a little bit. you saw nothing
+ initialized = true;
+
+ err = get_symbol(library->get_symbol_prefix() + init_symbol, library_init);
+
+ initialized = false;
if (err || !library_init) {
- OS::get_singleton()->close_dynamic_library(native_handle);
+ if (!library->is_current_library_statically_linked())
+ OS::get_singleton()->close_dynamic_library(native_handle);
native_handle = NULL;
ERR_PRINT("Failed to obtain godot_gdnative_init symbol");
return false;
@@ -260,18 +173,42 @@ bool GDNative::initialize() {
library_init_fpointer(&options);
+ initialized = true;
+
+ if (library->should_load_once() && !GDNativeLibrary::loaded_libraries->has(lib_path)) {
+ Vector<Ref<GDNative> > gdnatives;
+ gdnatives.resize(1);
+ gdnatives[0] = Ref<GDNative>(this);
+ GDNativeLibrary::loaded_libraries->insert(lib_path, gdnatives);
+ }
+
return true;
}
bool GDNative::terminate() {
- if (native_handle == NULL) {
+ if (!initialized) {
ERR_PRINT("No valid library handle, can't terminate GDNative object");
return false;
}
+ if (library->should_load_once()) {
+ Vector<Ref<GDNative> > *gdnatives = &(*GDNativeLibrary::loaded_libraries)[library->get_current_library_path()];
+ if (gdnatives->size() > 1) {
+ // there are other GDNative's still using this library, so we actually don't terminte
+ gdnatives->erase(Ref<GDNative>(this));
+ initialized = false;
+ return true;
+ } else if (gdnatives->size() == 1) {
+ // we're the last one, terminate!
+ gdnatives->clear();
+ // wew this looks scary, but all it does is remove the entry completely
+ GDNativeLibrary::loaded_libraries->erase(GDNativeLibrary::loaded_libraries->find(library->get_current_library_path()));
+ }
+ }
+
void *library_terminate;
- Error error = get_symbol(terminate_symbol, library_terminate);
+ Error error = get_symbol(library->get_symbol_prefix() + terminate_symbol, library_terminate);
if (error || !library_terminate) {
OS::get_singleton()->close_dynamic_library(native_handle);
native_handle = NULL;
@@ -281,13 +218,13 @@ bool GDNative::terminate() {
godot_gdnative_terminate_fn library_terminate_pointer;
library_terminate_pointer = (godot_gdnative_terminate_fn)library_terminate;
- // TODO(karroffel): remove this? Should be part of NativeScript, not
- // GDNative IMO
godot_gdnative_terminate_options options;
options.in_editor = Engine::get_singleton()->is_editor_hint();
library_terminate_pointer(&options);
+ initialized = false;
+
// GDNativeScriptLanguage::get_singleton()->initialized_libraries.erase(p_native_lib->path);
OS::get_singleton()->close_dynamic_library(native_handle);
@@ -297,7 +234,7 @@ bool GDNative::terminate() {
}
bool GDNative::is_initialized() {
- return (native_handle != NULL);
+ return initialized;
}
void GDNativeCallRegistry::register_native_call_type(StringName p_call_type, native_call_cb p_callback) {
@@ -342,7 +279,7 @@ Variant GDNative::call_native(StringName p_native_call_type, StringName p_proced
Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle) {
- if (native_handle == NULL) {
+ if (!initialized) {
ERR_PRINT("No valid library handle, can't get symbol from GDNative object");
return ERR_CANT_OPEN;
}
@@ -355,3 +292,159 @@ Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle) {
return result;
}
+
+RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error) {
+ Ref<GDNativeLibrary> lib;
+ lib.instance();
+
+ Ref<ConfigFile> config = lib->get_config_file();
+
+ Error err = config->load(p_path);
+
+ if (r_error) {
+ *r_error = err;
+ }
+
+ lib->set_singleton(config->get_value("general", "singleton", false));
+ lib->set_load_once(config->get_value("general", "load_once", true));
+ lib->set_symbol_prefix(config->get_value("general", "symbol_prefix", default_symbol_prefix));
+
+ String entry_lib_path;
+ {
+
+ List<String> entry_keys;
+ config->get_section_keys("entry", &entry_keys);
+
+ for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) {
+ String key = E->get();
+
+ Vector<String> tags = key.split(".");
+
+ bool skip = false;
+ for (int i = 0; i < tags.size(); i++) {
+ bool has_feature = OS::get_singleton()->has_feature(tags[i]);
+
+ if (!has_feature) {
+ skip = true;
+ break;
+ }
+ }
+
+ if (skip) {
+ continue;
+ }
+
+ entry_lib_path = config->get_value("entry", key);
+ break;
+ }
+ }
+
+ Vector<String> dependency_paths;
+ {
+
+ List<String> dependency_keys;
+ config->get_section_keys("dependencies", &dependency_keys);
+
+ for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) {
+ String key = E->get();
+
+ Vector<String> tags = key.split(".");
+
+ bool skip = false;
+ for (int i = 0; i < tags.size(); i++) {
+ bool has_feature = OS::get_singleton()->has_feature(tags[i]);
+
+ if (!has_feature) {
+ skip = true;
+ break;
+ }
+ }
+
+ if (skip) {
+ continue;
+ }
+
+ dependency_paths = config->get_value("dependencies", key);
+ break;
+ }
+ }
+
+ bool is_statically_linked = false;
+ {
+
+ List<String> static_linking_keys;
+ config->get_section_keys("static_linking", &static_linking_keys);
+
+ for (List<String>::Element *E = static_linking_keys.front(); E; E = E->next()) {
+ String key = E->get();
+
+ Vector<String> tags = key.split(".");
+
+ bool skip = false;
+
+ for (int i = 0; i < tags.size(); i++) {
+ bool has_feature = OS::get_singleton()->has_feature(tags[i]);
+
+ if (!has_feature) {
+ skip = true;
+ break;
+ }
+ }
+
+ if (skip) {
+ continue;
+ }
+
+ is_statically_linked = config->get_value("static_linking", key);
+ break;
+ }
+ }
+
+ lib->current_library_path = entry_lib_path;
+ lib->current_dependencies = dependency_paths;
+ lib->current_library_statically_linked = is_statically_linked;
+
+ return lib;
+}
+
+void GDNativeLibraryResourceLoader::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("gdnlib");
+}
+
+bool GDNativeLibraryResourceLoader::handles_type(const String &p_type) const {
+ return p_type == "GDNativeLibrary";
+}
+
+String GDNativeLibraryResourceLoader::get_resource_type(const String &p_path) const {
+ String el = p_path.get_extension().to_lower();
+ if (el == "gdnlib")
+ return "GDNativeLibrary";
+ return "";
+}
+
+Error GDNativeLibraryResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
+
+ Ref<GDNativeLibrary> lib = p_resource;
+
+ if (lib.is_null()) {
+ return ERR_INVALID_DATA;
+ }
+
+ Ref<ConfigFile> config = lib->get_config_file();
+
+ config->set_value("general", "singleton", lib->is_singleton());
+ config->set_value("general", "load_once", lib->should_load_once());
+ config->set_value("general", "symbol_prefix", lib->get_symbol_prefix());
+
+ return config->save(p_path);
+}
+
+bool GDNativeLibraryResourceSaver::recognize(const RES &p_resource) const {
+ return Object::cast_to<GDNativeLibrary>(*p_resource) != NULL;
+}
+
+void GDNativeLibraryResourceSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
+ if (Object::cast_to<GDNativeLibrary>(*p_resource) != NULL) {
+ p_extensions->push_back("gdnlib");
+ }
+}
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index e44cc55a79..061dff9267 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -38,66 +38,69 @@
#include "gdnative/gdnative.h"
#include "gdnative_api_struct.gen.h"
-class GDNativeLibrary : public Resource {
- GDCLASS(GDNativeLibrary, Resource)
-
- enum Platform {
- X11_32BIT,
- X11_64BIT,
- WINDOWS_32BIT,
- WINDOWS_64BIT,
- // NOTE(karroffel): I heard OSX 32 bit is dead, so 64 only
- OSX,
-
- // Android .so files must be located in directories corresponding to Android ABI names:
- // https://developer.android.com/ndk/guides/abis.html
- // Android runtime will select the matching library depending on the device.
- // The value here must simply point to the .so name, for example:
- // "res://libmy_gdnative.so" or "libmy_gdnative.so",
- // while in the project the actual paths can be "lib/android/armeabi-v7a/libmy_gdnative.so",
- // "lib/android/arm64-v8a/libmy_gdnative.so".
- ANDROID,
-
- IOS_32BIT,
- IOS_64BIT,
-
- // TODO(karroffel): figure out how to deal with web stuff at all...
- WASM,
-
- // TODO(karroffel): does UWP have different libs??
- // UWP,
+#include "io/config_file.h"
- NUM_PLATFORMS
+class GDNativeLibraryResourceLoader;
+class GDNative;
- };
+class GDNativeLibrary : public Resource {
+ GDCLASS(GDNativeLibrary, Resource)
- static String platform_names[NUM_PLATFORMS + 1];
- static String platform_lib_ext[NUM_PLATFORMS + 1];
+ static Map<String, Vector<Ref<GDNative> > > *loaded_libraries;
- static Platform current_platform;
+ friend class GDNativeLibraryResourceLoader;
+ friend class GDNative;
- String library_paths[NUM_PLATFORMS];
+ Ref<ConfigFile> config_file;
- bool singleton_gdnative;
+ String current_library_path;
+ Vector<String> current_dependencies;
+ bool current_library_statically_linked;
-protected:
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
+ bool singleton;
+ bool load_once;
+ String symbol_prefix;
public:
GDNativeLibrary();
~GDNativeLibrary();
- static void _bind_methods();
+ _FORCE_INLINE_ Ref<ConfigFile> get_config_file() { return config_file; }
+
+ // things that change per-platform
+ // so there are no setters for this
+ _FORCE_INLINE_ String get_current_library_path() const {
+ return current_library_path;
+ }
+ _FORCE_INLINE_ Vector<String> get_current_dependencies() const {
+ return current_dependencies;
+ }
+ _FORCE_INLINE_ bool is_current_library_statically_linked() const {
+ return current_library_statically_linked;
+ }
- void set_library_path(StringName p_platform, String p_path);
- String get_library_path(StringName p_platform) const;
+ // things that are a property of the library itself, not platform specific
+ _FORCE_INLINE_ bool should_load_once() const {
+ return load_once;
+ }
+ _FORCE_INLINE_ bool is_singleton() const {
+ return singleton;
+ }
+ _FORCE_INLINE_ String get_symbol_prefix() const {
+ return symbol_prefix;
+ }
- String get_active_library_path() const;
+ _FORCE_INLINE_ void set_load_once(bool p_load_once) {
+ load_once = p_load_once;
+ }
+ _FORCE_INLINE_ void set_singleton(bool p_singleton) {
+ singleton = p_singleton;
+ }
+ _FORCE_INLINE_ void set_symbol_prefix(String p_symbol_prefix) {
+ symbol_prefix = p_symbol_prefix;
+ }
- _FORCE_INLINE_ bool is_singleton_gdnative() const { return singleton_gdnative; }
- _FORCE_INLINE_ void set_singleton_gdnative(bool p_singleton) { singleton_gdnative = p_singleton; }
+ static void _bind_methods();
};
typedef godot_variant (*native_call_cb)(void *, godot_array *);
@@ -124,10 +127,9 @@ class GDNative : public Reference {
Ref<GDNativeLibrary> library;
- // TODO(karroffel): different platforms? WASM????
void *native_handle;
- void _compile_dummy_for_api();
+ bool initialized;
public:
GDNative();
@@ -148,4 +150,19 @@ public:
Error get_symbol(StringName p_procedure_name, void *&r_handle);
};
+class GDNativeLibraryResourceLoader : public ResourceFormatLoader {
+public:
+ virtual RES load(const String &p_path, const String &p_original_path, Error *r_error);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
+};
+
+class GDNativeLibraryResourceSaver : public ResourceFormatSaver {
+public:
+ virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags);
+ virtual bool recognize(const RES &p_resource) const;
+ virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
+};
+
#endif // GDNATIVE_H
diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp
index 90bc4dc031..e0d9514985 100644
--- a/modules/gdnative/gdnative/array.cpp
+++ b/modules/gdnative/gdnative/array.cpp
@@ -41,9 +41,6 @@
extern "C" {
#endif
-void _array_api_anchor() {
-}
-
void GDAPI godot_array_new(godot_array *r_dest) {
Array *dest = (Array *)r_dest;
memnew_placement(dest, Array);
diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp
index 28af93f942..39ca754dc7 100644
--- a/modules/gdnative/gdnative/basis.cpp
+++ b/modules/gdnative/gdnative/basis.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _basis_api_anchor() {}
-
void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis) {
const Vector3 *x_axis = (const Vector3 *)p_x_axis;
const Vector3 *y_axis = (const Vector3 *)p_y_axis;
diff --git a/modules/gdnative/gdnative/color.cpp b/modules/gdnative/gdnative/color.cpp
index 2a5c0887a1..281a4c416f 100644
--- a/modules/gdnative/gdnative/color.cpp
+++ b/modules/gdnative/gdnative/color.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _color_api_anchor() {}
-
void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a) {
Color *dest = (Color *)r_dest;
diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp
index 7f8320622d..8363416946 100644
--- a/modules/gdnative/gdnative/dictionary.cpp
+++ b/modules/gdnative/gdnative/dictionary.cpp
@@ -38,8 +38,6 @@
extern "C" {
#endif
-void _dictionary_api_anchor() {}
-
void GDAPI godot_dictionary_new(godot_dictionary *r_dest) {
Dictionary *dest = (Dictionary *)r_dest;
memnew_placement(dest, Dictionary);
diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp
index f11ff90116..6dfa7ec20b 100644
--- a/modules/gdnative/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative/gdnative.cpp
@@ -40,47 +40,6 @@
extern "C" {
#endif
-extern "C" void _string_api_anchor();
-extern "C" void _string_name_api_anchor();
-extern "C" void _vector2_api_anchor();
-extern "C" void _rect2_api_anchor();
-extern "C" void _vector3_api_anchor();
-extern "C" void _transform2d_api_anchor();
-extern "C" void _plane_api_anchor();
-extern "C" void _quat_api_anchor();
-extern "C" void _basis_api_anchor();
-extern "C" void _rect3_api_anchor();
-extern "C" void _transform_api_anchor();
-extern "C" void _color_api_anchor();
-extern "C" void _node_path_api_anchor();
-extern "C" void _rid_api_anchor();
-extern "C" void _dictionary_api_anchor();
-extern "C" void _array_api_anchor();
-extern "C" void _pool_arrays_api_anchor();
-extern "C" void _variant_api_anchor();
-
-void _api_anchor() {
-
- _string_api_anchor();
- _string_name_api_anchor();
- _vector2_api_anchor();
- _rect2_api_anchor();
- _vector3_api_anchor();
- _transform2d_api_anchor();
- _plane_api_anchor();
- _quat_api_anchor();
- _rect3_api_anchor();
- _basis_api_anchor();
- _transform_api_anchor();
- _color_api_anchor();
- _node_path_api_anchor();
- _rid_api_anchor();
- _dictionary_api_anchor();
- _array_api_anchor();
- _pool_arrays_api_anchor();
- _variant_api_anchor();
-}
-
void GDAPI godot_object_destroy(godot_object *p_o) {
memdelete((Object *)p_o);
}
@@ -133,14 +92,6 @@ godot_variant GDAPI godot_method_bind_call(godot_method_bind *p_method_bind, god
return ret;
}
-// @Todo
-/*
-void GDAPI godot_method_bind_varcall(godot_method_bind *p_method_bind)
-{
-
-}
-*/
-
godot_class_constructor GDAPI godot_get_class_constructor(const char *p_classname) {
ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(StringName(p_classname));
if (class_info)
diff --git a/modules/gdnative/gdnative/node_path.cpp b/modules/gdnative/gdnative/node_path.cpp
index 50fade5b94..2bd278e050 100644
--- a/modules/gdnative/gdnative/node_path.cpp
+++ b/modules/gdnative/gdnative/node_path.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _node_path_api_anchor() {}
-
void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from) {
NodePath *dest = (NodePath *)r_dest;
const String *from = (const String *)p_from;
diff --git a/modules/gdnative/gdnative/plane.cpp b/modules/gdnative/gdnative/plane.cpp
index a5e05ffa6b..c92efb8d99 100644
--- a/modules/gdnative/gdnative/plane.cpp
+++ b/modules/gdnative/gdnative/plane.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _plane_api_anchor() {}
-
void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d) {
Plane *dest = (Plane *)r_dest;
diff --git a/modules/gdnative/gdnative/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp
index 731e930908..562cc344a9 100644
--- a/modules/gdnative/gdnative/pool_arrays.cpp
+++ b/modules/gdnative/gdnative/pool_arrays.cpp
@@ -41,9 +41,6 @@
extern "C" {
#endif
-void _pool_arrays_api_anchor() {
-}
-
#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
// byte
diff --git a/modules/gdnative/gdnative/quat.cpp b/modules/gdnative/gdnative/quat.cpp
index 7db7847da1..2d012c069f 100644
--- a/modules/gdnative/gdnative/quat.cpp
+++ b/modules/gdnative/gdnative/quat.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _quat_api_anchor() {}
-
void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w) {
Quat *dest = (Quat *)r_dest;
diff --git a/modules/gdnative/gdnative/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp
index ecd8cce9ca..b0b0e28138 100644
--- a/modules/gdnative/gdnative/rect2.cpp
+++ b/modules/gdnative/gdnative/rect2.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _rect2_api_anchor() {}
-
void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size) {
const Vector2 *position = (const Vector2 *)p_pos;
const Vector2 *size = (const Vector2 *)p_size;
diff --git a/modules/gdnative/gdnative/rect3.cpp b/modules/gdnative/gdnative/rect3.cpp
index d34d964db9..8e088743b4 100644
--- a/modules/gdnative/gdnative/rect3.cpp
+++ b/modules/gdnative/gdnative/rect3.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _rect3_api_anchor() {}
-
void GDAPI godot_rect3_new(godot_rect3 *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size) {
const Vector3 *pos = (const Vector3 *)p_pos;
const Vector3 *size = (const Vector3 *)p_size;
diff --git a/modules/gdnative/gdnative/rid.cpp b/modules/gdnative/gdnative/rid.cpp
index f05c39906c..c6e8d82494 100644
--- a/modules/gdnative/gdnative/rid.cpp
+++ b/modules/gdnative/gdnative/rid.cpp
@@ -37,8 +37,6 @@
extern "C" {
#endif
-void _rid_api_anchor() {}
-
void GDAPI godot_rid_new(godot_rid *r_dest) {
RID *dest = (RID *)r_dest;
memnew_placement(dest, RID);
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 619003083d..781b8754bd 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -39,9 +39,6 @@
extern "C" {
#endif
-void _string_api_anchor() {
-}
-
void GDAPI godot_string_new(godot_string *r_dest) {
String *dest = (String *)r_dest;
memnew_placement(dest, String);
diff --git a/modules/gdnative/gdnative/string_name.cpp b/modules/gdnative/gdnative/string_name.cpp
index 5c00fdfc2f..5c79e0acbd 100644
--- a/modules/gdnative/gdnative/string_name.cpp
+++ b/modules/gdnative/gdnative/string_name.cpp
@@ -38,9 +38,6 @@
extern "C" {
#endif
-void _string_name_api_anchor() {
-}
-
void GDAPI godot_string_name_new(godot_string_name *r_dest, const godot_string *p_name) {
StringName *dest = (StringName *)r_dest;
const String *name = (const String *)p_name;
diff --git a/modules/gdnative/gdnative/transform.cpp b/modules/gdnative/gdnative/transform.cpp
index d7a3e78d3f..96b2ec8a7a 100644
--- a/modules/gdnative/gdnative/transform.cpp
+++ b/modules/gdnative/gdnative/transform.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _transform_api_anchor() {}
-
void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin) {
const Vector3 *x_axis = (const Vector3 *)p_x_axis;
const Vector3 *y_axis = (const Vector3 *)p_y_axis;
diff --git a/modules/gdnative/gdnative/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp
index dcb54f7a53..0a6334516b 100644
--- a/modules/gdnative/gdnative/transform2d.cpp
+++ b/modules/gdnative/gdnative/transform2d.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _transform2d_api_anchor() {}
-
void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos) {
const Vector2 *pos = (const Vector2 *)p_pos;
Transform2D *dest = (Transform2D *)r_dest;
diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp
index 9ba4166c1d..0c31bc643c 100644
--- a/modules/gdnative/gdnative/variant.cpp
+++ b/modules/gdnative/gdnative/variant.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _variant_api_anchor() {}
-
#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
// Constructors
diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp
index 67f858997f..7a5b29e0c4 100644
--- a/modules/gdnative/gdnative/vector2.cpp
+++ b/modules/gdnative/gdnative/vector2.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _vector2_api_anchor() {}
-
void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y) {
Vector2 *dest = (Vector2 *)r_dest;
diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp
index c85a3f1c08..11ffb3320b 100644
--- a/modules/gdnative/gdnative/vector3.cpp
+++ b/modules/gdnative/gdnative/vector3.cpp
@@ -36,8 +36,6 @@
extern "C" {
#endif
-void _vector3_api_anchor() {}
-
void GDAPI godot_vector3_new(godot_vector3 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z) {
Vector3 *dest = (Vector3 *)r_dest;
diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index 8fa96fd3af..a479eced16 100644
--- a/modules/gdnative/include/gdnative/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -53,7 +53,7 @@ extern "C" {
// This is for libraries *using* the header, NOT GODOT EXPOSING STUFF!!
#ifdef _WIN32
-#define GDN_EXPORT __declspec(dllexport)
+#define GDN_EXPORT
#else
#define GDN_EXPORT
#endif
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index c1df7def2e..c2c7c27f25 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -40,6 +40,8 @@
#include "scene/main/scene_tree.h"
#include "scene/resources/scene_format_text.h"
+#include <stdlib.h>
+
#ifndef NO_THREADS
#include "os/thread.h"
#endif
@@ -52,7 +54,11 @@
#include "editor/editor_node.h"
#endif
-////// Script stuff
+//
+//
+// Script stuff
+//
+//
void NativeScript::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_class_name", "class_name"), &NativeScript::set_class_name);
@@ -108,7 +114,7 @@ void NativeScript::set_library(Ref<GDNativeLibrary> p_library) {
return;
}
library = p_library;
- lib_path = library->get_active_library_path();
+ lib_path = library->get_current_library_path();
#ifndef NO_THREADS
if (Thread::get_caller_id() != Thread::get_main_id()) {
@@ -414,7 +420,6 @@ Variant NativeScript::_new(const Variant **p_args, int p_argcount, Variant::Call
}
}
-// TODO(karroffel): implement this
NativeScript::NativeScript() {
library = Ref<GDNative>();
lib_path = "";
@@ -424,7 +429,6 @@ NativeScript::NativeScript() {
#endif
}
-// TODO(karroffel): implement this
NativeScript::~NativeScript() {
NSL->unregister_script(this);
@@ -433,7 +437,11 @@ NativeScript::~NativeScript() {
#endif
}
-////// ScriptInstance stuff
+//
+//
+// ScriptInstance stuff
+//
+//
#define GET_SCRIPT_DESC() script->get_script_desc()
@@ -691,7 +699,6 @@ NativeScriptInstance::RPCMode NativeScriptInstance::get_rpc_mode(const StringNam
return RPC_MODE_DISABLED;
}
-// TODO(karroffel): implement this
NativeScriptInstance::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const {
NativeScriptDesc *script_data = GET_SCRIPT_DESC();
@@ -774,15 +781,14 @@ NativeScriptInstance::~NativeScriptInstance() {
}
}
-////// ScriptingLanguage stuff
+//
+//
+// ScriptingLanguage stuff
+//
+//
NativeScriptLanguage *NativeScriptLanguage::singleton;
-extern "C" void _native_script_hook();
-void NativeScriptLanguage::_hacky_api_anchor() {
- _native_script_hook();
-}
-
void NativeScriptLanguage::_unload_stuff() {
for (Map<String, Map<StringName, NativeScriptDesc> >::Element *L = library_classes.front(); L; L = L->next()) {
for (Map<StringName, NativeScriptDesc>::Element *C = L->get().front(); C; C = C->next()) {
@@ -819,9 +825,7 @@ NativeScriptLanguage::NativeScriptLanguage() {
#endif
}
-// TODO(karroffel): implement this
NativeScriptLanguage::~NativeScriptLanguage() {
- // _unload_stuff(); // NOTE(karroffel): This gets called in ::finish()
for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
@@ -847,7 +851,6 @@ void _add_reload_node() {
#endif
}
-// TODO(karroffel): implement this
void NativeScriptLanguage::init() {
#if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED)
@@ -860,6 +863,7 @@ void NativeScriptLanguage::init() {
if (generate_c_api(E->next()->get()) != OK) {
ERR_PRINT("Failed to generate C API\n");
}
+ exit(0);
}
#endif
@@ -886,11 +890,9 @@ void NativeScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) co
void NativeScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const {
}
-// TODO(karroffel): implement this
Ref<Script> NativeScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
NativeScript *s = memnew(NativeScript);
s->set_class_name(p_class_name);
- // TODO(karroffel): use p_base_class_name
return Ref<NativeScript>(s);
}
bool NativeScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const {
@@ -988,7 +990,7 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
MutexLock lock(mutex);
#endif
// See if this library was "registered" already.
- const String &lib_path = lib->get_active_library_path();
+ const String &lib_path = lib->get_current_library_path();
ERR_EXPLAIN(lib->get_name() + " does not have a library for the current platform");
ERR_FAIL_COND(lib_path.length() == 0);
Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path);
@@ -998,7 +1000,7 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
gdn.instance();
gdn->set_library(lib);
- // TODO(karroffel): check the return value?
+ // TODO check the return value?
gdn->initialize();
library_gdnatives.insert(lib_path, gdn);
@@ -1010,7 +1012,7 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
void *proc_ptr;
- Error err = gdn->get_symbol(_init_call_name, proc_ptr);
+ Error err = gdn->get_symbol(lib->get_symbol_prefix() + _init_call_name, proc_ptr);
if (err != OK) {
ERR_PRINT(String("No " + _init_call_name + " in \"" + lib_path + "\" found").utf8().get_data());
@@ -1051,7 +1053,7 @@ void NativeScriptLanguage::call_libraries_cb(const StringName &name) {
if (L->get()->is_initialized()) {
void *proc_ptr;
- Error err = L->get()->get_symbol(name, proc_ptr);
+ Error err = L->get()->get_symbol(L->get()->get_library()->get_symbol_prefix() + name, proc_ptr);
if (!err) {
((void (*)())proc_ptr)();
@@ -1140,7 +1142,7 @@ void NativeReloadNode::_notification(int p_what) {
// here the library registers all the classes and stuff.
void *proc_ptr;
- Error err = L->get()->get_symbol("godot_nativescript_init", proc_ptr);
+ Error err = L->get()->get_symbol(L->get()->get_library()->get_symbol_prefix() + "nativescript_init", proc_ptr);
if (err != OK) {
ERR_PRINT(String("No godot_nativescript_init in \"" + L->key() + "\" found").utf8().get_data());
} else {
diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index e8fc9e6880..f0f14e2f30 100644
--- a/modules/gdnative/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -229,15 +229,15 @@ public:
Map<String, Set<NativeScript *> > library_script_users;
const StringName _init_call_type = "nativescript_init";
- const StringName _init_call_name = "godot_nativescript_init";
+ const StringName _init_call_name = "nativescript_init";
const StringName _noarg_call_type = "nativescript_no_arg";
- const StringName _frame_call_name = "godot_nativescript_frame";
+ const StringName _frame_call_name = "nativescript_frame";
#ifndef NO_THREADS
- const StringName _thread_enter_call_name = "godot_nativescript_thread_enter";
- const StringName _thread_exit_call_name = "godot_nativescript_thread_exit";
+ const StringName _thread_enter_call_name = "nativescript_thread_enter";
+ const StringName _thread_exit_call_name = "nativescript_thread_exit";
#endif
NativeScriptLanguage();
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index 19a62b9c4f..ca69f2eca2 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -81,7 +81,7 @@ Set<String> get_gdnative_singletons(EditorFileSystemDirectory *p_dir) {
}
Ref<GDNativeLibrary> lib = ResourceLoader::load(p_dir->get_file_path(i));
- if (lib.is_valid() && lib->is_singleton_gdnative()) {
+ if (lib.is_valid() && lib->is_singleton()) {
file_paths.insert(p_dir->get_file_path(i));
}
}
@@ -141,6 +141,9 @@ GDNativeCallRegistry *GDNativeCallRegistry::singleton;
Vector<Ref<GDNative> > singleton_gdnatives;
+GDNativeLibraryResourceLoader *resource_loader_gdnlib = NULL;
+GDNativeLibraryResourceSaver *resource_saver_gdnlib = NULL;
+
void register_gdnative_types() {
#ifdef TOOLS_ENABLED
@@ -153,6 +156,12 @@ void register_gdnative_types() {
ClassDB::register_class<GDNativeLibrary>();
ClassDB::register_class<GDNative>();
+ resource_loader_gdnlib = memnew(GDNativeLibraryResourceLoader);
+ resource_saver_gdnlib = memnew(GDNativeLibraryResourceSaver);
+
+ ResourceLoader::add_resource_format_loader(resource_loader_gdnlib);
+ ResourceSaver::add_resource_format_saver(resource_saver_gdnlib);
+
GDNativeCallRegistry::singleton = memnew(GDNativeCallRegistry);
GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall);
@@ -185,11 +194,11 @@ void register_gdnative_types() {
void *proc_ptr;
Error err = singleton_gdnatives[i]->get_symbol(
- "godot_gdnative_singleton",
+ lib->get_symbol_prefix() + "gdnative_singleton",
proc_ptr);
if (err != OK) {
- ERR_PRINT((String("No godot_gdnative_singleton in \"" + singleton_gdnatives[i]->get_library()->get_active_library_path()) + "\" found").utf8().get_data());
+ ERR_PRINT((String("No godot_gdnative_singleton in \"" + singleton_gdnatives[i]->get_library()->get_current_library_path()) + "\" found").utf8().get_data());
} else {
((void (*)())proc_ptr)();
}
@@ -224,6 +233,9 @@ void unregister_gdnative_types() {
}
#endif
+ memdelete(resource_loader_gdnlib);
+ memdelete(resource_saver_gdnlib);
+
// This is for printing out the sizes of the core types
/*
diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp
index 346b7d326a..655e785174 100644
--- a/modules/gdscript/gd_editor.cpp
+++ b/modules/gdscript/gd_editor.cpp
@@ -365,7 +365,7 @@ String GDScriptLanguage::make_function(const String &p_class, const String &p_na
}
s += " ";
}
- s += "):\n\tpass # replace with function body\n";
+ s += "):\n" + _get_indentation() + "pass # replace with function body\n";
return s;
}
diff --git a/modules/ogg/config.py b/modules/ogg/config.py
index ef5daca05c..fb920482f5 100644
--- a/modules/ogg/config.py
+++ b/modules/ogg/config.py
@@ -1,7 +1,6 @@
def can_build(platform):
-# return True
- return False
+ return True
def configure(env):
diff --git a/modules/opus/SCsub b/modules/opus/SCsub
index fee06bd267..6f643ef08c 100644
--- a/modules/opus/SCsub
+++ b/modules/opus/SCsub
@@ -3,6 +3,9 @@
Import('env')
Import('env_modules')
+
+stub = True
+
env_opus = env_modules.Clone()
# Thirdparty source files
@@ -212,5 +215,9 @@ if env['builtin_opus']:
if env['builtin_libogg']:
env_opus.Append(CPPPATH=["#thirdparty/libogg"])
-# Module files
-env_opus.add_source_files(env.modules_sources, "*.cpp")
+if not stub:
+ # Module files
+ env_opus.add_source_files(env.modules_sources, "*.cpp")
+else:
+ # Module files
+ env_opus.add_source_files(env.modules_sources, "stub/register_types.cpp")
diff --git a/modules/opus/config.py b/modules/opus/config.py
index ef5daca05c..fb920482f5 100644
--- a/modules/opus/config.py
+++ b/modules/opus/config.py
@@ -1,7 +1,6 @@
def can_build(platform):
-# return True
- return False
+ return True
def configure(env):
diff --git a/modules/opus/stub/register_types.cpp b/modules/opus/stub/register_types.cpp
new file mode 100644
index 0000000000..c5ae3e274e
--- /dev/null
+++ b/modules/opus/stub/register_types.cpp
@@ -0,0 +1,36 @@
+/*************************************************************************/
+/* register_types.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. */
+/*************************************************************************/
+#include "register_types.h"
+
+// Dummy module as libvorbis is needed by other modules (theora ...)
+
+void register_opus_types() {}
+
+void unregister_opus_types() {}
diff --git a/modules/opus/stub/register_types.h b/modules/opus/stub/register_types.h
new file mode 100644
index 0000000000..4517dc5df7
--- /dev/null
+++ b/modules/opus/stub/register_types.h
@@ -0,0 +1,31 @@
+/*************************************************************************/
+/* register_types.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. */
+/*************************************************************************/
+void register_opus_types();
+void unregister_opus_types();
diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp
index 00e8ce0f54..daadfcc659 100644
--- a/modules/regex/regex.cpp
+++ b/modules/regex/regex.cpp
@@ -324,6 +324,21 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end)
return result;
}
+Array RegEx::search_all(const String &p_subject, int p_offset, int p_end) const {
+
+ int last_end = -1;
+ Array result;
+ Ref<RegExMatch> match = search(p_subject, p_offset, p_end);
+ while (match.is_valid()) {
+ if (last_end == match->get_end(0))
+ break;
+ result.push_back(match);
+ last_end = match->get_end(0);
+ match = search(p_subject, match->get_end(0), p_end);
+ }
+ return result;
+}
+
String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_all, int p_offset, int p_end) const {
ERR_FAIL_COND_V(!is_valid(), String());
@@ -489,6 +504,7 @@ void RegEx::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &RegEx::clear);
ClassDB::bind_method(D_METHOD("compile", "pattern"), &RegEx::compile);
ClassDB::bind_method(D_METHOD("search", "subject", "offset", "end"), &RegEx::search, DEFVAL(0), DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("search_all", "subject", "offset", "end"), &RegEx::search_all, DEFVAL(0), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("sub", "subject", "replacement", "all", "offset", "end"), &RegEx::sub, DEFVAL(false), DEFVAL(0), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("is_valid"), &RegEx::is_valid);
ClassDB::bind_method(D_METHOD("get_pattern"), &RegEx::get_pattern);
diff --git a/modules/regex/regex.h b/modules/regex/regex.h
index bfa9c84042..21387222f2 100644
--- a/modules/regex/regex.h
+++ b/modules/regex/regex.h
@@ -88,6 +88,7 @@ public:
void _init(const String &p_pattern = "");
Ref<RegExMatch> search(const String &p_subject, int p_offset = 0, int p_end = -1) const;
+ Array search_all(const String &p_subject, int p_offset = 0, int p_end = -1) const;
String sub(const String &p_subject, const String &p_replacement, bool p_all = false, int p_offset = 0, int p_end = -1) const;
bool is_valid() const;
diff --git a/modules/theora/config.py b/modules/theora/config.py
index 8eefe81288..fb920482f5 100644
--- a/modules/theora/config.py
+++ b/modules/theora/config.py
@@ -1,7 +1,6 @@
def can_build(platform):
-# return True
- return False
+ return True
def configure(env):
diff --git a/modules/theora/register_types.cpp b/modules/theora/register_types.cpp
index ae6961b3da..c51b87b8fc 100644
--- a/modules/theora/register_types.cpp
+++ b/modules/theora/register_types.cpp
@@ -28,19 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "register_types.h"
-
+#include "resource_importer_theora.h"
#include "video_stream_theora.h"
-static ResourceFormatLoaderVideoStreamTheora *theora_stream_loader = NULL;
-
void register_theora_types() {
- theora_stream_loader = memnew(ResourceFormatLoaderVideoStreamTheora);
- ResourceLoader::add_resource_format_loader(theora_stream_loader);
+#ifdef TOOLS_ENABLED
+ Ref<ResourceImporterTheora> theora_import;
+ theora_import.instance();
+ ResourceFormatImporter::get_singleton()->add_importer(theora_import);
+#endif
ClassDB::register_class<VideoStreamTheora>();
}
void unregister_theora_types() {
-
- memdelete(theora_stream_loader);
}
diff --git a/modules/theora/resource_importer_theora.cpp b/modules/theora/resource_importer_theora.cpp
new file mode 100644
index 0000000000..c25c0e7427
--- /dev/null
+++ b/modules/theora/resource_importer_theora.cpp
@@ -0,0 +1,89 @@
+/*************************************************************************/
+/* resource_importer_theora.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. */
+/*************************************************************************/
+#include "resource_importer_theora.h"
+
+#include "io/resource_saver.h"
+#include "os/file_access.h"
+#include "scene/resources/texture.h"
+
+String ResourceImporterTheora::get_importer_name() const {
+
+ return "Theora";
+}
+
+String ResourceImporterTheora::get_visible_name() const {
+
+ return "Theora";
+}
+void ResourceImporterTheora::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("ogv");
+ p_extensions->push_back("ogm");
+}
+
+String ResourceImporterTheora::get_save_extension() const {
+ return "ogvstr";
+}
+
+String ResourceImporterTheora::get_resource_type() const {
+
+ return "VideoStreamTheora";
+}
+
+bool ResourceImporterTheora::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+
+ return true;
+}
+
+int ResourceImporterTheora::get_preset_count() const {
+ return 0;
+}
+String ResourceImporterTheora::get_preset_name(int p_idx) const {
+
+ return String();
+}
+
+void ResourceImporterTheora::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true));
+}
+
+Error ResourceImporterTheora::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {
+
+ VideoStreamTheora *stream = memnew(VideoStreamTheora);
+ stream->set_file(p_source_file);
+
+ Ref<VideoStreamTheora> ogv_stream = Ref<VideoStreamTheora>(stream);
+
+ return ResourceSaver::save(p_save_path + ".ogvstr", ogv_stream);
+}
+
+ResourceImporterTheora::ResourceImporterTheora() {
+}
diff --git a/modules/theora/resource_importer_theora.h b/modules/theora/resource_importer_theora.h
new file mode 100644
index 0000000000..8bf0ad38c4
--- /dev/null
+++ b/modules/theora/resource_importer_theora.h
@@ -0,0 +1,57 @@
+/*************************************************************************/
+/* resource_importer_theora.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 RESOURCEIMPORTEROGGTHEORA_H
+#define RESOURCEIMPORTEROGGTHEORA_H
+
+#include "video_stream_theora.h"
+
+#include "core/io/resource_import.h"
+
+class ResourceImporterTheora : public ResourceImporter {
+ GDCLASS(ResourceImporterTheora, ResourceImporter)
+public:
+ virtual String get_importer_name() const;
+ virtual String get_visible_name() const;
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual String get_save_extension() const;
+ virtual String get_resource_type() const;
+
+ virtual int get_preset_count() const;
+ virtual String get_preset_name(int p_idx) const;
+
+ virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
+ virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
+
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
+
+ ResourceImporterTheora();
+};
+
+#endif // RESOURCEIMPORTEROGGTHEORA_H
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index c75bec31df..bc8ca23d60 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -406,20 +406,19 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
ogg_packet op;
bool no_theora = false;
+ bool buffer_full = false;
- while (vorbis_p) {
+ while (vorbis_p && !audio_done && !buffer_full) {
int ret;
float **pcm;
- bool buffer_full = false;
-
/* if there's pending, decoded audio, grab it */
ret = vorbis_synthesis_pcmout(&vd, &pcm);
if (ret > 0) {
const int AUXBUF_LEN = 4096;
int to_read = ret;
- int16_t aux_buffer[AUXBUF_LEN];
+ float aux_buffer[AUXBUF_LEN];
while (to_read) {
@@ -429,11 +428,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
for (int j = 0; j < m; j++) {
for (int i = 0; i < vi.channels; i++) {
-
- int val = Math::fast_ftoi(pcm[i][j] * 32767.f);
- if (val > 32767) val = 32767;
- if (val < -32768) val = -32768;
- aux_buffer[count++] = val;
+ aux_buffer[count++] = pcm[i][j];
}
}
@@ -602,10 +597,9 @@ bool VideoStreamPlaybackTheora::is_playing() const {
void VideoStreamPlaybackTheora::set_paused(bool p_paused) {
paused = p_paused;
- //pau = !p_paused;
};
-bool VideoStreamPlaybackTheora::is_paused(bool p_paused) const {
+bool VideoStreamPlaybackTheora::is_paused() const {
return paused;
};
@@ -733,32 +727,10 @@ VideoStreamPlaybackTheora::~VideoStreamPlaybackTheora() {
memdelete(file);
};
-RES ResourceFormatLoaderVideoStreamTheora::load(const String &p_path, const String &p_original_path, Error *r_error) {
- if (r_error)
- *r_error = ERR_FILE_CANT_OPEN;
-
- VideoStreamTheora *stream = memnew(VideoStreamTheora);
- stream->set_file(p_path);
-
- if (r_error)
- *r_error = OK;
-
- return Ref<VideoStreamTheora>(stream);
-}
+void VideoStreamTheora::_bind_methods() {
-void ResourceFormatLoaderVideoStreamTheora::get_recognized_extensions(List<String> *p_extensions) const {
+ ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamTheora::set_file);
+ ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamTheora::get_file);
- p_extensions->push_back("ogm");
- p_extensions->push_back("ogv");
-}
-bool ResourceFormatLoaderVideoStreamTheora::handles_type(const String &p_type) const {
- return (p_type == "VideoStream" || p_type == "VideoStreamTheora");
-}
-
-String ResourceFormatLoaderVideoStreamTheora::get_resource_type(const String &p_path) const {
-
- String exl = p_path.get_extension().to_lower();
- if (exl == "ogm" || exl == "ogv")
- return "VideoStreamTheora";
- return "";
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_file", "get_file");
}
diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h
index 484a1a7fb9..ec0e5aa34a 100644
--- a/modules/theora/video_stream_theora.h
+++ b/modules/theora/video_stream_theora.h
@@ -36,6 +36,7 @@
#include "os/thread.h"
#include "ring_buffer.h"
#include "scene/resources/video_stream.h"
+#include "servers/audio_server.h"
#include <theora/theoradec.h>
#include <vorbis/codec.h>
@@ -129,7 +130,7 @@ public:
virtual bool is_playing() const;
virtual void set_paused(bool p_paused);
- virtual bool is_paused(bool p_paused) const;
+ virtual bool is_paused() const;
virtual void set_loop(bool p_enable);
virtual bool has_loop() const;
@@ -161,10 +162,14 @@ public:
class VideoStreamTheora : public VideoStream {
GDCLASS(VideoStreamTheora, VideoStream);
+ RES_BASE_EXTENSION("ogvstr");
String file;
int audio_track;
+protected:
+ static void _bind_methods();
+
public:
Ref<VideoStreamPlayback> instance_playback() {
Ref<VideoStreamPlaybackTheora> pb = memnew(VideoStreamPlaybackTheora);
@@ -174,17 +179,10 @@ public:
}
void set_file(const String &p_file) { file = p_file; }
+ String get_file() { return file; }
void set_audio_track(int p_track) { audio_track = p_track; }
VideoStreamTheora() { audio_track = 0; }
};
-class ResourceFormatLoaderVideoStreamTheora : public ResourceFormatLoader {
-public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
- virtual void get_recognized_extensions(List<String> *p_extensions) const;
- virtual bool handles_type(const String &p_type) const;
- virtual String get_resource_type(const String &p_path) const;
-};
-
#endif
diff --git a/modules/vorbis/SCsub b/modules/vorbis/SCsub
index 9d2d0feb92..55a112585b 100644
--- a/modules/vorbis/SCsub
+++ b/modules/vorbis/SCsub
@@ -5,6 +5,8 @@ Import('env_modules')
env_vorbis = env_modules.Clone()
+stub = True
+
# Thirdparty source files
if env['builtin_libvorbis']:
thirdparty_dir = "#thirdparty/libvorbis/"
@@ -45,5 +47,9 @@ if env['builtin_libvorbis']:
if env['builtin_libogg']:
env_vorbis.Append(CPPPATH=["#thirdparty/libogg"])
-# Godot source files
-env_vorbis.add_source_files(env.modules_sources, "*.cpp")
+if not stub:
+ # Module files
+ env_vorbis.add_source_files(env.modules_sources, "*.cpp")
+else:
+ # Module files
+ env_vorbis.add_source_files(env.modules_sources, "stub/register_types.cpp")
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp
index 6235799fc2..9fb6fa8197 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp
@@ -106,8 +106,6 @@ int AudioStreamPlaybackOGGVorbis::mix(int16_t *p_buffer, int p_frames) {
break;
}
-//printf("to mix %i - mix me %i bytes\n",to_mix,to_mix*stream_channels*sizeof(int16_t));
-
#ifdef BIG_ENDIAN_ENABLED
long ret = ov_read(&vf, (char *)p_buffer, todo * stream_channels * sizeof(int16_t), 1, 2, 1, &current_section);
#else
@@ -359,7 +357,7 @@ void AudioStreamPlaybackOGGVorbis::set_paused(bool p_paused) {
paused = p_paused;
}
-bool AudioStreamPlaybackOGGVorbis::is_paused(bool p_paused) const {
+bool AudioStreamPlaybackOGGVorbis::is_paused() const {
return paused;
}
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.h b/modules/vorbis/audio_stream_ogg_vorbis.h
index 79eadec56e..5000d03fd4 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.h
+++ b/modules/vorbis/audio_stream_ogg_vorbis.h
@@ -85,7 +85,7 @@ public:
virtual void set_loop_restart_time(float p_time) { loop_restart_time = p_time; }
virtual void set_paused(bool p_paused);
- virtual bool is_paused(bool p_paused) const;
+ virtual bool is_paused() const;
virtual void set_loop(bool p_enable);
virtual bool has_loop() const;
diff --git a/modules/vorbis/config.py b/modules/vorbis/config.py
index ef5daca05c..fb920482f5 100644
--- a/modules/vorbis/config.py
+++ b/modules/vorbis/config.py
@@ -1,7 +1,6 @@
def can_build(platform):
-# return True
- return False
+ return True
def configure(env):
diff --git a/modules/vorbis/stub/register_types.cpp b/modules/vorbis/stub/register_types.cpp
new file mode 100644
index 0000000000..b93d890436
--- /dev/null
+++ b/modules/vorbis/stub/register_types.cpp
@@ -0,0 +1,36 @@
+/*************************************************************************/
+/* register_types.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. */
+/*************************************************************************/
+#include "register_types.h"
+
+// Dummy module as libvorbis is needed by other modules (theora ...)
+
+void register_vorbis_types() {}
+
+void unregister_vorbis_types() {}
diff --git a/modules/vorbis/stub/register_types.h b/modules/vorbis/stub/register_types.h
new file mode 100644
index 0000000000..e7cde7a66c
--- /dev/null
+++ b/modules/vorbis/stub/register_types.h
@@ -0,0 +1,31 @@
+/*************************************************************************/
+/* register_types.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. */
+/*************************************************************************/
+void register_vorbis_types();
+void unregister_vorbis_types();
diff --git a/modules/webm/config.py b/modules/webm/config.py
index ef5daca05c..fb920482f5 100644
--- a/modules/webm/config.py
+++ b/modules/webm/config.py
@@ -1,7 +1,6 @@
def can_build(platform):
-# return True
- return False
+ return True
def configure(env):
diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub
index fd8d762a5e..73ba17d184 100644
--- a/modules/webm/libvpx/SCsub
+++ b/modules/webm/libvpx/SCsub
@@ -298,7 +298,7 @@ if webm_cpu_x86:
if not yasm_found:
webm_cpu_x86 = False
- print "YASM is necessary for WebM SIMD optimizations."
+ print("YASM is necessary for WebM SIMD optimizations.")
webm_simd_optimizations = False
@@ -345,7 +345,7 @@ if webm_cpu_arm:
webm_simd_optimizations = True
if webm_simd_optimizations == False:
- print "WebM SIMD optimizations are disabled. Check if your CPU architecture, CPU bits or platform are supported!"
+ print("WebM SIMD optimizations are disabled. Check if your CPU architecture, CPU bits or platform are supported!")
env_libvpx.add_source_files(env.modules_sources, libvpx_sources)
diff --git a/modules/webm/register_types.cpp b/modules/webm/register_types.cpp
index 892d1b8420..669c9997f1 100644
--- a/modules/webm/register_types.cpp
+++ b/modules/webm/register_types.cpp
@@ -28,19 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "register_types.h"
-
+#include "resource_importer_webm.h"
#include "video_stream_webm.h"
-static ResourceFormatLoaderVideoStreamWebm *webm_stream_loader = NULL;
-
void register_webm_types() {
- webm_stream_loader = memnew(ResourceFormatLoaderVideoStreamWebm);
- ResourceLoader::add_resource_format_loader(webm_stream_loader);
+#ifdef TOOLS_ENABLED
+ Ref<ResourceImporterWebm> webm_import;
+ webm_import.instance();
+ ResourceFormatImporter::get_singleton()->add_importer(webm_import);
+#endif
ClassDB::register_class<VideoStreamWebm>();
}
void unregister_webm_types() {
-
- memdelete(webm_stream_loader);
}
diff --git a/modules/webm/resource_importer_webm.cpp b/modules/webm/resource_importer_webm.cpp
new file mode 100644
index 0000000000..5db3d4df2e
--- /dev/null
+++ b/modules/webm/resource_importer_webm.cpp
@@ -0,0 +1,95 @@
+/*************************************************************************/
+/* resource_importer_webm.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. */
+/*************************************************************************/
+#include "resource_importer_webm.h"
+
+#include "io/resource_saver.h"
+#include "os/file_access.h"
+#include "scene/resources/texture.h"
+#include "video_stream_webm.h"
+
+String ResourceImporterWebm::get_importer_name() const {
+
+ return "Webm";
+}
+
+String ResourceImporterWebm::get_visible_name() const {
+
+ return "Webm";
+}
+void ResourceImporterWebm::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("webm");
+}
+
+String ResourceImporterWebm::get_save_extension() const {
+ return "webmstr";
+}
+
+String ResourceImporterWebm::get_resource_type() const {
+
+ return "VideoStreamWebm";
+}
+
+bool ResourceImporterWebm::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+
+ return true;
+}
+
+int ResourceImporterWebm::get_preset_count() const {
+ return 0;
+}
+String ResourceImporterWebm::get_preset_name(int p_idx) const {
+
+ return String();
+}
+
+void ResourceImporterWebm::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true));
+}
+
+Error ResourceImporterWebm::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {
+
+ FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ);
+ if (!f) {
+ ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+ }
+ memdelete(f);
+
+ VideoStreamWebm *stream = memnew(VideoStreamWebm);
+ stream->set_file(p_source_file);
+
+ Ref<VideoStreamWebm> webm_stream = Ref<VideoStreamWebm>(stream);
+
+ return ResourceSaver::save(p_save_path + ".webmstr", webm_stream);
+}
+
+ResourceImporterWebm::ResourceImporterWebm() {
+}
diff --git a/modules/webm/resource_importer_webm.h b/modules/webm/resource_importer_webm.h
new file mode 100644
index 0000000000..4cedd1598d
--- /dev/null
+++ b/modules/webm/resource_importer_webm.h
@@ -0,0 +1,55 @@
+/*************************************************************************/
+/* resource_importer_webm.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 RESOURCEIMPORTERWEBM_H
+#define RESOURCEIMPORTERWEBM_H
+
+#include "io/resource_import.h"
+
+class ResourceImporterWebm : public ResourceImporter {
+ GDCLASS(ResourceImporterWebm, ResourceImporter)
+public:
+ virtual String get_importer_name() const;
+ virtual String get_visible_name() const;
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual String get_save_extension() const;
+ virtual String get_resource_type() const;
+
+ virtual int get_preset_count() const;
+ virtual String get_preset_name(int p_idx) const;
+
+ virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
+ virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
+
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
+
+ ResourceImporterWebm();
+};
+
+#endif // RESOURCEIMPORTERWEBM_H
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index 2ec6b27471..0fc9df5b58 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -35,10 +35,13 @@
#include "mkvparser/mkvparser.h"
#include "os/file_access.h"
+#include "os/os.h"
#include "project_settings.h"
#include "thirdparty/misc/yuv2rgb.h"
+#include "servers/audio_server.h"
+
#include <string.h>
class MkvReader : public mkvparser::IMkvReader {
@@ -47,6 +50,8 @@ public:
MkvReader(const String &p_file) {
file = FileAccess::open(p_file, FileAccess::READ);
+
+ ERR_EXPLAIN("Failed loading resource: '" + p_file + "';");
ERR_FAIL_COND(!file);
}
~MkvReader() {
@@ -113,14 +118,14 @@ bool VideoStreamPlaybackWebm::open_file(const String &p_file) {
webm = memnew(WebMDemuxer(new MkvReader(file_name), 0, audio_track));
if (webm->isOpen()) {
- video = memnew(VPXDecoder(*webm, 8)); //TODO: Detect CPU threads
+ video = memnew(VPXDecoder(*webm, OS::get_singleton()->get_processor_count()));
if (video->isOpen()) {
audio = memnew(OpusVorbisDecoder(*webm));
if (audio->isOpen()) {
audio_frame = memnew(WebMFrame);
- pcm = (int16_t *)memalloc(sizeof(int16_t) * audio->getBufferSamples() * webm->getChannels());
+ pcm = (float *)memalloc(sizeof(float) * audio->getBufferSamples() * webm->getChannels());
} else {
memdelete(audio);
@@ -183,7 +188,7 @@ void VideoStreamPlaybackWebm::set_paused(bool p_paused) {
paused = p_paused;
}
-bool VideoStreamPlaybackWebm::is_paused(bool p_paused) const {
+bool VideoStreamPlaybackWebm::is_paused() const {
return paused;
}
@@ -222,11 +227,18 @@ Ref<Texture> VideoStreamPlaybackWebm::get_texture() {
return texture;
}
+
void VideoStreamPlaybackWebm::update(float p_delta) {
if ((!playing || paused) || !video)
return;
+ time += p_delta;
+
+ if (time < video_pos) {
+ return;
+ }
+
bool audio_buffer_full = false;
if (samples_offset > -1) {
@@ -245,13 +257,15 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
}
const bool hasAudio = (audio && mix_callback);
- while ((hasAudio && (!audio_buffer_full || !has_enough_video_frames())) || (!hasAudio && video_frames_pos == 0)) {
+ while ((hasAudio && !audio_buffer_full && !has_enough_video_frames()) ||
+ (!hasAudio && video_frames_pos == 0)) {
- if (hasAudio && !audio_buffer_full && audio_frame->isValid() && audio->getPCMS16(*audio_frame, pcm, num_decoded_samples) && num_decoded_samples > 0) {
+ if (hasAudio && !audio_buffer_full && audio_frame->isValid() &&
+ audio->getPCMF(*audio_frame, pcm, num_decoded_samples) && num_decoded_samples > 0) {
const int mixed = mix_callback(mix_udata, pcm, num_decoded_samples);
- if (mixed != num_decoded_samples) {
+ if (mixed != num_decoded_samples) {
samples_offset = mixed;
audio_buffer_full = true;
}
@@ -273,72 +287,61 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
++video_frames_pos;
};
- const double video_delay = video->getFramesDelay() * video_frame_delay;
-
- bool want_this_frame = false;
- while (video_frames_pos > 0 && !want_this_frame) {
+ bool video_frame_done = false;
+ while (video_frames_pos > 0 && !video_frame_done) {
WebMFrame *video_frame = video_frames[0];
- if (video_frame->time <= time + video_delay) {
- if (video->decode(*video_frame)) {
+ // It seems VPXDecoder::decode has to be executed even though we might skip this frame
+ if (video->decode(*video_frame)) {
- VPXDecoder::IMAGE_ERROR err;
- VPXDecoder::Image image;
+ VPXDecoder::IMAGE_ERROR err;
+ VPXDecoder::Image image;
- while ((err = video->getImage(image)) != VPXDecoder::NO_FRAME) {
+ if (should_process(*video_frame)) {
- want_this_frame = (time - video_frame->time <= video_frame_delay);
+ if ((err = video->getImage(image)) != VPXDecoder::NO_FRAME) {
- if (want_this_frame) {
+ if (err == VPXDecoder::NO_ERROR && image.w == webm->getWidth() && image.h == webm->getHeight()) {
- if (err == VPXDecoder::NO_ERROR && image.w == webm->getWidth() && image.h == webm->getHeight()) {
+ PoolVector<uint8_t>::Write w = frame_data.write();
+ bool converted = false;
- PoolVector<uint8_t>::Write w = frame_data.write();
- bool converted = false;
+ if (image.chromaShiftW == 1 && image.chromaShiftH == 1) {
- if (image.chromaShiftW == 1 && image.chromaShiftH == 1) {
+ yuv420_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0);
+ // libyuv::I420ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
+ converted = true;
+ } else if (image.chromaShiftW == 1 && image.chromaShiftH == 0) {
- yuv420_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0);
- // libyuv::I420ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
- converted = true;
- } else if (image.chromaShiftW == 1 && image.chromaShiftH == 0) {
+ yuv422_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0);
+ // libyuv::I422ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
+ converted = true;
+ } else if (image.chromaShiftW == 0 && image.chromaShiftH == 0) {
- yuv422_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0);
- // libyuv::I422ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
- converted = true;
- } else if (image.chromaShiftW == 0 && image.chromaShiftH == 0) {
+ yuv444_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0);
+ // libyuv::I444ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
+ converted = true;
+ } else if (image.chromaShiftW == 2 && image.chromaShiftH == 0) {
- yuv444_2_rgb8888(w.ptr(), image.planes[0], image.planes[2], image.planes[1], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2, 0);
- // libyuv::I444ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
- converted = true;
- } else if (image.chromaShiftW == 2 && image.chromaShiftH == 0) {
-
- // libyuv::I411ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
- // converted = true;
- }
-
- if (converted)
- texture->set_data(Image(image.w, image.h, 0, Image::FORMAT_RGBA8, frame_data)); //Zero copy send to visual server
+ // libyuv::I411ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
+ // converted = true;
}
- break;
+ if (converted) {
+ Ref<Image> img = memnew(Image(image.w, image.h, 0, Image::FORMAT_RGBA8, frame_data));
+ texture->set_data(img); //Zero copy send to visual server
+ video_frame_done = true;
+ }
}
}
}
-
- video_frame_delay = video_frame->time - video_pos;
- video_pos = video_frame->time;
-
- memmove(video_frames, video_frames + 1, (--video_frames_pos) * sizeof(void *));
- video_frames[video_frames_pos] = video_frame;
- } else {
-
- break;
}
- }
- time += p_delta;
+ video_pos = video_frame->time;
+ memmove(video_frames, video_frames + 1, (--video_frames_pos) * sizeof(void *));
+ video_frames[video_frames_pos] = video_frame;
+ }
if (video_frames_pos == 0 && webm->isEOS())
stop();
@@ -372,6 +375,11 @@ inline bool VideoStreamPlaybackWebm::has_enough_video_frames() const {
return false;
}
+bool VideoStreamPlaybackWebm::should_process(WebMFrame &video_frame) {
+ const double audio_delay = AudioServer::get_singleton()->get_output_delay();
+ return video_frame.time >= time + audio_delay + delay_compensation;
+}
+
void VideoStreamPlaybackWebm::delete_pointers() {
if (pcm)
@@ -395,34 +403,6 @@ void VideoStreamPlaybackWebm::delete_pointers() {
/**/
-RES ResourceFormatLoaderVideoStreamWebm::load(const String &p_path, const String &p_original_path, Error *r_error) {
-
- Ref<VideoStreamWebm> stream = memnew(VideoStreamWebm);
- stream->set_file(p_path);
- if (r_error)
- *r_error = OK;
- return stream;
-}
-
-void ResourceFormatLoaderVideoStreamWebm::get_recognized_extensions(List<String> *p_extensions) const {
-
- p_extensions->push_back("webm");
-}
-bool ResourceFormatLoaderVideoStreamWebm::handles_type(const String &p_type) const {
-
- return (p_type == "VideoStream" || p_type == "VideoStreamWebm");
-}
-
-String ResourceFormatLoaderVideoStreamWebm::get_resource_type(const String &p_path) const {
-
- const String exl = p_path.get_extension().to_lower();
- if (exl == "webm")
- return "VideoStreamWebm";
- return "";
-}
-
-/**/
-
VideoStreamWebm::VideoStreamWebm()
: audio_track(0) {}
@@ -439,6 +419,19 @@ void VideoStreamWebm::set_file(const String &p_file) {
file = p_file;
}
+String VideoStreamWebm::get_file() {
+
+ return file;
+}
+
+void VideoStreamWebm::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamWebm::set_file);
+ ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamWebm::get_file);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "file", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_file", "get_file");
+}
+
void VideoStreamWebm::set_audio_track(int p_track) {
audio_track = p_track;
diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h
index fc0720967a..f7dd16a38f 100644
--- a/modules/webm/video_stream_webm.h
+++ b/modules/webm/video_stream_webm.h
@@ -60,7 +60,7 @@ class VideoStreamPlaybackWebm : public VideoStreamPlayback {
PoolVector<uint8_t> frame_data;
Ref<ImageTexture> texture;
- int16_t *pcm;
+ float *pcm;
public:
VideoStreamPlaybackWebm();
@@ -74,7 +74,7 @@ public:
virtual bool is_playing() const;
virtual void set_paused(bool p_paused);
- virtual bool is_paused(bool p_paused) const;
+ virtual bool is_paused() const;
virtual void set_loop(bool p_enable);
virtual bool has_loop() const;
@@ -95,6 +95,7 @@ public:
private:
inline bool has_enough_video_frames() const;
+ bool should_process(WebMFrame &video_frame);
void delete_pointers();
};
@@ -103,27 +104,21 @@ private:
class VideoStreamWebm : public VideoStream {
- GDCLASS(VideoStreamWebm, VideoStream)
+ GDCLASS(VideoStreamWebm, VideoStream);
+ RES_BASE_EXTENSION("webmstr");
String file;
int audio_track;
+protected:
+ static void _bind_methods();
+
public:
VideoStreamWebm();
virtual Ref<VideoStreamPlayback> instance_playback();
virtual void set_file(const String &p_file);
+ String get_file();
virtual void set_audio_track(int p_track);
};
-
-/**/
-
-class ResourceFormatLoaderVideoStreamWebm : public ResourceFormatLoader {
-
-public:
- virtual RES load(const String &p_path, const String &p_original_path, Error *r_error);
- virtual void get_recognized_extensions(List<String> *p_extensions) const;
- virtual bool handles_type(const String &p_type) const;
- virtual String get_resource_type(const String &p_path) const;
-};