summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp21
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp1
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h3
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp91
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp25
-rw-r--r--drivers/gles3/shaders/scene.glsl50
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp170
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.h11
-rw-r--r--drivers/rtaudio/audio_driver_rtaudio.cpp2
-rw-r--r--drivers/unix/SCsub2
-rw-r--r--drivers/unix/dir_access_unix.cpp114
-rw-r--r--drivers/unix/file_access_unix.cpp11
-rw-r--r--drivers/unix/file_access_unix.h4
-rw-r--r--drivers/unix/socket_helpers.h1
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp8
-rw-r--r--drivers/windows/file_access_windows.cpp9
-rw-r--r--drivers/windows/file_access_windows.h2
17 files changed, 381 insertions, 144 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 84f29facf4..5d62d2f5a0 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -576,6 +576,15 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
Rect2 src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.position * texpixel_size, rect->source.size * texpixel_size) : Rect2(0, 0, 1, 1);
Rect2 dst_rect = Rect2(rect->rect.position, rect->rect.size);
+ if (dst_rect.size.width < 0) {
+ dst_rect.position.x += dst_rect.size.width;
+ dst_rect.size.width *= -1;
+ }
+ if (dst_rect.size.height < 0) {
+ dst_rect.position.y += dst_rect.size.height;
+ dst_rect.size.height *= -1;
+ }
+
if (rect->flags & CANVAS_RECT_FLIP_H) {
src_rect.size.x *= -1;
}
@@ -602,8 +611,18 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
}
} else {
+ Rect2 dst_rect = Rect2(rect->rect.position, rect->rect.size);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(rect->rect.position.x, rect->rect.position.y, rect->rect.size.x, rect->rect.size.y));
+ if (dst_rect.size.width < 0) {
+ dst_rect.position.x += dst_rect.size.width;
+ dst_rect.size.width *= -1;
+ }
+ if (dst_rect.size.height < 0) {
+ dst_rect.position.y += dst_rect.size.height;
+ dst_rect.size.height *= -1;
+ }
+
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y));
state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(0, 0, 1, 1));
state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, false);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 146a2359b6..98a9211d0c 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -2404,6 +2404,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
//store camera into ubo
store_camera(p_cam_projection, state.ubo_data.projection_matrix);
+ store_camera(p_cam_projection.inverse(), state.ubo_data.inv_projection_matrix);
store_transform(p_cam_transform, state.ubo_data.camera_matrix);
store_transform(p_cam_transform.affine_inverse(), state.ubo_data.camera_inverse_matrix);
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index b3fd6fa2a0..04cb3597da 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -110,6 +110,7 @@ public:
struct SceneDataUBO {
//this is a std140 compatible struct. Please read the OpenGL 3.3 Specificaiton spec before doing any changes
float projection_matrix[16];
+ float inv_projection_matrix[16];
float camera_inverse_matrix[16];
float camera_matrix[16];
float ambient_light_color[4];
@@ -806,7 +807,7 @@ public:
void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows);
- _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_passs);
+ _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass);
_FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 3cacfac578..ae41a936c6 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -165,7 +165,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
} break;
case Image::FORMAT_RGB8: {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? GL_SRGB8 : GL_RGB8;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? GL_SRGB8 : GL_RGB8;
r_gl_format = GL_RGB;
r_gl_type = GL_UNSIGNED_BYTE;
srgb = true;
@@ -174,7 +174,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
case Image::FORMAT_RGBA8: {
r_gl_format = GL_RGBA;
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
r_gl_type = GL_UNSIGNED_BYTE;
srgb = true;
@@ -254,7 +254,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
if (config.s3tc_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -270,7 +270,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
if (config.s3tc_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -286,7 +286,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
if (config.s3tc_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -331,7 +331,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
if (config.bptc_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM : _EXT_COMPRESSED_RGBA_BPTC_UNORM;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM : _EXT_COMPRESSED_RGBA_BPTC_UNORM;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -371,7 +371,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
if (config.pvrtc_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT : _EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT : _EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -386,7 +386,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
if (config.pvrtc_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT : _EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT : _EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -402,7 +402,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
if (config.pvrtc_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT : _EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT : _EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -418,7 +418,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
if (config.pvrtc_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT : _EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT : _EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -503,7 +503,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
if (config.etc2_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB8_ETC2 : _EXT_COMPRESSED_RGB8_ETC2;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB8_ETC2 : _EXT_COMPRESSED_RGB8_ETC2;
r_gl_format = GL_RGB;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -518,7 +518,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
if (config.etc2_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : _EXT_COMPRESSED_RGBA8_ETC2_EAC;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : _EXT_COMPRESSED_RGBA8_ETC2_EAC;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -533,7 +533,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
if (config.etc2_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : _EXT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : _EXT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -560,7 +560,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_
}
r_gl_format = GL_RGBA;
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
+ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = false;
srgb = true;
@@ -595,7 +595,6 @@ RID RasterizerStorageGLES3::texture_create() {
void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags) {
- int components;
GLenum format;
GLenum internal_format;
GLenum type;
@@ -686,7 +685,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
texture->ignore_mipmaps = compressed && !img->has_mipmaps();
- if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps)
+ if ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && !texture->ignore_mipmaps)
glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, config.use_fast_texture_filter ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR);
else {
if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
@@ -717,7 +716,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering
}
- if ((texture->flags & VS::TEXTURE_FLAG_REPEAT || texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) {
+ if (((texture->flags & VS::TEXTURE_FLAG_REPEAT) || (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT)) && texture->target != GL_TEXTURE_CUBE_MAP) {
if (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
@@ -770,15 +769,13 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
}
}
- int mipmaps = (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && img->has_mipmaps()) ? img->get_mipmap_count() + 1 : 1;
+ int mipmaps = ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && img->has_mipmaps()) ? img->get_mipmap_count() + 1 : 1;
int w = img->get_width();
int h = img->get_height();
int tsize = 0;
- int block = Image::get_format_block_size(img->get_format());
-
for (int i = 0; i < mipmaps; i++) {
int size, ofs;
@@ -789,10 +786,6 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
if (texture->compressed) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- //this is not needed, as compressed takes the regular size, even if blocks extend it
- //int bw = (w % block != 0) ? w + (block - w % block) : w;
- //int bh = (h % block != 0) ? h + (block - h % block) : h;
-
int bw = w;
int bh = h;
@@ -820,7 +813,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
texture->stored_cube_sides |= (1 << p_cube_side);
- if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && mipmaps == 1 && !texture->ignore_mipmaps && (!(texture->flags & VS::TEXTURE_FLAG_CUBEMAP) || texture->stored_cube_sides == (1 << 6) - 1)) {
+ if ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && mipmaps == 1 && !texture->ignore_mipmaps && (!(texture->flags & VS::TEXTURE_FLAG_CUBEMAP) || texture->stored_cube_sides == (1 << 6) - 1)) {
//generate mipmaps if they were requested and the image does not contain them
glGenerateMipmap(texture->target);
} else if (mipmaps > 1) {
@@ -912,7 +905,7 @@ void RasterizerStorageGLES3::texture_set_flags(RID p_texture, uint32_t p_flags)
uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP;
texture->flags = p_flags | cube; // can't remove a cube from being a cube
- if ((texture->flags & VS::TEXTURE_FLAG_REPEAT || texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) {
+ if (((texture->flags & VS::TEXTURE_FLAG_REPEAT) || (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT)) && texture->target != GL_TEXTURE_CUBE_MAP) {
if (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
@@ -937,7 +930,7 @@ void RasterizerStorageGLES3::texture_set_flags(RID p_texture, uint32_t p_flags)
}
}
- if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) {
+ if ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && !texture->ignore_mipmaps) {
if (!had_mipmaps && texture->mipmaps == 1) {
glGenerateMipmap(texture->target);
}
@@ -1571,6 +1564,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->canvas_item.blend_mode = Shader::CanvasItem::BLEND_MODE_MIX;
p_shader->canvas_item.uses_screen_texture = false;
p_shader->canvas_item.uses_screen_uv = false;
+ p_shader->canvas_item.uses_time = false;
shaders.actions_canvas.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_ADD);
shaders.actions_canvas.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MIX);
@@ -1602,6 +1596,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->spatial.unshaded = false;
p_shader->spatial.no_depth_test = false;
p_shader->spatial.uses_sss = false;
+ p_shader->spatial.uses_time = false;
p_shader->spatial.uses_vertex_lighting = false;
p_shader->spatial.uses_screen_texture = false;
p_shader->spatial.uses_vertex = false;
@@ -3360,7 +3355,7 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
for (int i = 0; i < mesh->surfaces.size(); i++) {
Rect3 laabb;
- if (mesh->surfaces[i]->format & VS::ARRAY_FORMAT_BONES && mesh->surfaces[i]->skeleton_bone_aabb.size()) {
+ if ((mesh->surfaces[i]->format & VS::ARRAY_FORMAT_BONES) && mesh->surfaces[i]->skeleton_bone_aabb.size()) {
int bs = mesh->surfaces[i]->skeleton_bone_aabb.size();
const Rect3 *skbones = mesh->surfaces[i]->skeleton_bone_aabb.ptr();
@@ -4631,7 +4626,7 @@ void RasterizerStorageGLES3::light_directional_set_shadow_depth_range_mode(RID p
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
- light->directional_range_mode=p_range_mode;
+ light->directional_range_mode = p_range_mode;
}
VS::LightDirectionalShadowDepthRangeMode RasterizerStorageGLES3::light_directional_get_shadow_depth_range_mode(RID p_light) const {
@@ -6864,42 +6859,28 @@ int RasterizerStorageGLES3::get_captured_render_info(VS::RenderInfo p_info) {
int RasterizerStorageGLES3::get_render_info(VS::RenderInfo p_info) {
switch (p_info) {
- case VS::INFO_OBJECTS_IN_FRAME: {
-
+ case VS::INFO_OBJECTS_IN_FRAME:
return info.render_final.object_count;
- } break;
- case VS::INFO_VERTICES_IN_FRAME: {
-
+ case VS::INFO_VERTICES_IN_FRAME:
return info.render_final.vertices_count;
- } break;
- case VS::INFO_MATERIAL_CHANGES_IN_FRAME: {
+ case VS::INFO_MATERIAL_CHANGES_IN_FRAME:
return info.render_final.material_switch_count;
- } break;
- case VS::INFO_SHADER_CHANGES_IN_FRAME: {
+ case VS::INFO_SHADER_CHANGES_IN_FRAME:
return info.render_final.shader_rebind_count;
- } break;
- case VS::INFO_SURFACE_CHANGES_IN_FRAME: {
+ case VS::INFO_SURFACE_CHANGES_IN_FRAME:
return info.render_final.surface_switch_count;
- } break;
- case VS::INFO_DRAW_CALLS_IN_FRAME: {
+ case VS::INFO_DRAW_CALLS_IN_FRAME:
return info.render_final.draw_call_count;
- } break;
- case VS::INFO_USAGE_VIDEO_MEM_TOTAL: {
-
+ case VS::INFO_USAGE_VIDEO_MEM_TOTAL:
return 0; //no idea
- } break;
- case VS::INFO_VIDEO_MEM_USED: {
-
+ case VS::INFO_VIDEO_MEM_USED:
return info.vertex_mem + info.texture_mem;
- } break;
- case VS::INFO_TEXTURE_MEM_USED: {
-
+ case VS::INFO_TEXTURE_MEM_USED:
return info.texture_mem;
- } break;
- case VS::INFO_VERTEX_MEM_USED: {
-
+ case VS::INFO_VERTEX_MEM_USED:
return info.vertex_mem;
- } break;
+ default:
+ return 0; //no idea either
}
}
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 419decce29..9a5b53c84b 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -441,12 +441,12 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
if (!bnode->single_statement) {
code += _mktab(p_level - 1) + "{\n";
}
-
+
for (int i = 0; i < bnode->statements.size(); i++) {
String scode = _dump_node_code(bnode->statements[i], p_level, r_gen_code, p_actions, p_default_actions);
- if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement ) {
+ if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement) {
code += scode; //use directly
} else {
code += _mktab(p_level) + scode + ";\n";
@@ -461,20 +461,20 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
SL::VariableDeclarationNode *vdnode = (SL::VariableDeclarationNode *)p_node;
String declaration = _prestr(vdnode->precision) + _typestr(vdnode->datatype);
- for(int i=0;i<vdnode->declarations.size();i++) {
- if (i>0) {
- declaration+=",";
+ for (int i = 0; i < vdnode->declarations.size(); i++) {
+ if (i > 0) {
+ declaration += ",";
} else {
- declaration+=" ";
+ declaration += " ";
}
- declaration += _mkid(vdnode->declarations[i].name);
+ declaration += _mkid(vdnode->declarations[i].name);
if (vdnode->declarations[i].initializer) {
- declaration+="=";
- declaration+=_dump_node_code(vdnode->declarations[i].initializer, p_level, r_gen_code, p_actions, p_default_actions);
+ declaration += "=";
+ declaration += _dump_node_code(vdnode->declarations[i].initializer, p_level, r_gen_code, p_actions, p_default_actions);
}
}
- code+=declaration;
+ code += declaration;
} break;
case SL::Node::TYPE_VARIABLE: {
SL::VariableNode *vnode = (SL::VariableNode *)p_node;
@@ -623,7 +623,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
String left = _dump_node_code(cfnode->blocks[0], p_level, r_gen_code, p_actions, p_default_actions);
String middle = _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions);
String right = _dump_node_code(cfnode->expressions[1], p_level, r_gen_code, p_actions, p_default_actions);
- code += _mktab(p_level) + "for (" +left+";"+middle+";"+right+")\n";
+ code += _mktab(p_level) + "for (" + left + ";" + middle + ";" + right + ")\n";
code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions);
} else if (cfnode->flow_op == SL::FLOW_OP_RETURN) {
@@ -750,6 +750,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"] = "camera_inverse_matrix";
actions[VS::SHADER_SPATIAL].renames["CAMERA_MATRIX"] = "camera_matrix";
actions[VS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"] = "projection_matrix";
+ actions[VS::SHADER_SPATIAL].renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix";
actions[VS::SHADER_SPATIAL].renames["MODELVIEW_MATRIX"] = "modelview";
actions[VS::SHADER_SPATIAL].renames["VERTEX"] = "vertex.xyz";
@@ -786,6 +787,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
actions[VS::SHADER_SPATIAL].renames["TRANSMISSION"] = "transmission";
actions[VS::SHADER_SPATIAL].renames["AO"] = "ao";
+ actions[VS::SHADER_SPATIAL].renames["AO_LIGHT_AFFECT"] = "ao_light_affect";
actions[VS::SHADER_SPATIAL].renames["EMISSION"] = "emission";
//actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2;
actions[VS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord";
@@ -805,6 +807,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].usage_defines["ANISOTROPY"] = "#define LIGHT_USE_ANISOTROPY\n";
actions[VS::SHADER_SPATIAL].usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY";
actions[VS::SHADER_SPATIAL].usage_defines["AO"] = "#define ENABLE_AO\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["AO_LIGHT_AFFECT"] = "#define ENABLE_AO\n";
actions[VS::SHADER_SPATIAL].usage_defines["UV"] = "#define ENABLE_UV_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["UV2"] = "#define ENABLE_UV2_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP"] = "#define ENABLE_NORMALMAP\n";
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 73268c1914..25115bc18a 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -61,6 +61,7 @@ layout(location=12) in highp vec4 instance_custom_data;
layout(std140) uniform SceneData { //ubo:0
highp mat4 projection_matrix;
+ highp mat4 inv_projection_matrix;
highp mat4 camera_inverse_matrix;
highp mat4 camera_matrix;
@@ -643,6 +644,7 @@ FRAGMENT_SHADER_GLOBALS
layout(std140) uniform SceneData {
highp mat4 projection_matrix;
+ highp mat4 inv_projection_matrix;
highp mat4 camera_inverse_matrix;
highp mat4 camera_matrix;
@@ -887,7 +889,7 @@ float GTR1(float NdotH, float a)
-void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) {
+void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 attenuation,vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) {
#if defined(USE_LIGHT_SHADER_CODE)
//light is written by the light shader
@@ -935,17 +937,26 @@ LIGHT_SHADER_CODE
#elif defined(DIFFUSE_BURLEY)
{
- float NdotL = dot(L, N);
- float NdotV = dot(N, V);
- float VdotH = dot(N, normalize(L+V));
+
+
+ vec3 H = normalize(V + L);
+ float NoL = max(0.0,dot(N, L));
+ float VoH = max(0.0,dot(L, H));
+ float NoV = max(0.0,dot(N, V));
+
+ float FD90 = 0.5 + 2.0 * VoH * VoH * roughness;
+ float FdV = 1.0 + (FD90 - 1.0) * pow( 1.0 - NoV, 5.0 );
+ float FdL = 1.0 + (FD90 - 1.0) * pow( 1.0 - NoL, 5.0 );
+ light_amount = ( (1.0 / M_PI) * FdV * FdL );
+/*
float energyBias = mix(roughness, 0.0, 0.5);
float energyFactor = mix(roughness, 1.0, 1.0 / 1.51);
- float fd90 = energyBias + 2.0 * VdotH * VdotH * roughness;
+ float fd90 = energyBias + 2.0 * VoH * VoH * roughness;
float f0 = 1.0;
- float lightScatter = f0 + (fd90 - f0) * pow(1.0 - NdotL, 5.0);
- float viewScatter = f0 + (fd90 - f0) * pow(1.0 - NdotV, 5.0);
+ float lightScatter = f0 + (fd90 - f0) * pow(1.0 - NoL, 5.0);
+ float viewScatter = f0 + (fd90 - f0) * pow(1.0 - NoV, 5.0);
- light_amount = lightScatter * viewScatter * energyFactor;
+ light_amount = lightScatter * viewScatter * energyFactor;*/
}
#else
//lambert
@@ -953,9 +964,9 @@ LIGHT_SHADER_CODE
#endif
#if defined(TRANSMISSION_USED)
- diffuse += light_color * diffuse_color * mix(vec3(light_amount),vec3(1.0),transmission);
+ diffuse += light_color * diffuse_color * mix(vec3(light_amount),vec3(1.0),transmission) * attenuation;
#else
- diffuse += light_color * diffuse_color * light_amount;
+ diffuse += light_color * diffuse_color * light_amount * attenuation;
#endif
@@ -976,14 +987,14 @@ LIGHT_SHADER_CODE
vec3 H = normalize(V + L);
float dotNH = max(dot(N,H), 0.0 );
float intensity = pow( dotNH, (1.0-roughness) * 256.0);
- specular += light_color * intensity * specular_blob_intensity;
+ specular += light_color * intensity * specular_blob_intensity * attenuation;
#elif defined(SPECULAR_PHONG)
vec3 R = normalize(-reflect(L,N));
float dotNV = max(0.0,dot(R,V));
float intensity = pow( dotNV, (1.0-roughness) * 256.0);
- specular += light_color * intensity * specular_blob_intensity;
+ specular += light_color * intensity * specular_blob_intensity * attenuation;
#elif defined(SPECULAR_TOON)
@@ -992,7 +1003,7 @@ LIGHT_SHADER_CODE
float mid = 1.0-roughness;
mid*=mid;
float intensity = smoothstep(mid-roughness*0.5,mid+roughness*0.5,dotNV) * mid;
- diffuse += light_color * intensity * specular_blob_intensity; //write to diffuse, as in toon shading you generally want no reflection
+ diffuse += light_color * intensity * specular_blob_intensity * attenuation; //write to diffuse, as in toon shading you generally want no reflection
#elif defined(SPECULAR_DISABLED)
//none..
@@ -1036,7 +1047,7 @@ LIGHT_SHADER_CODE
float speci = dotNL * D * F * vis;
- specular += speci * light_color * specular_blob_intensity;
+ specular += speci * light_color * specular_blob_intensity * attenuation;
#endif
#if defined(LIGHT_USE_CLEARCOAT)
@@ -1182,7 +1193,7 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 bino
light_attenuation*=mix(omni_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
- light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,transmission,omni_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb,light_attenuation,albedo,transmission,omni_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
@@ -1216,7 +1227,7 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
light_attenuation*=mix(spot_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
- light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,transmission,spot_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb,light_attenuation,albedo,transmission,spot_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
@@ -1525,6 +1536,7 @@ void main() {
#if defined(ENABLE_AO)
float ao=1.0;
+ float ao_light_affect=0.0;
#endif
float alpha = 1.0;
@@ -1848,7 +1860,7 @@ FRAGMENT_SHADER_CODE
specular_light*=mix(vec3(1.0),light_attenuation,specular_light_interp.a);
#else
- light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,transmission,light_params.z*specular_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb,light_attenuation,albedo,transmission,light_params.z*specular_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
#endif
@@ -1909,9 +1921,13 @@ FRAGMENT_SHADER_CODE
#if defined(ENABLE_AO)
ambient_light*=ao;
+ ao_light_affect = mix(1.0,ao,ao_light_affect);
+ specular_light*=ao_light_affect;
+ diffuse_light*=ao_light_affect;
#endif
+
//energu conservation
diffuse_light=mix(diffuse_light,vec3(0.0),metallic);
ambient_light=mix(ambient_light,vec3(0.0),metallic);
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
index 1798c84d85..e4c8641a3b 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
@@ -31,23 +31,144 @@
#ifdef PULSEAUDIO_ENABLED
-#include <pulse/error.h>
+#include <pulse/pulseaudio.h>
#include "os/os.h"
#include "project_settings.h"
+void pa_state_cb(pa_context *c, void *userdata) {
+ pa_context_state_t state;
+ int *pa_ready = (int *)userdata;
+
+ state = pa_context_get_state(c);
+ switch (state) {
+ case PA_CONTEXT_FAILED:
+ case PA_CONTEXT_TERMINATED:
+ *pa_ready = 2;
+ break;
+
+ case PA_CONTEXT_READY:
+ *pa_ready = 1;
+ break;
+ }
+}
+
+void sink_info_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata) {
+ unsigned int *channels = (unsigned int *)userdata;
+
+ // If eol is set to a positive number, you're at the end of the list
+ if (eol > 0) {
+ return;
+ }
+
+ *channels = l->channel_map.channels;
+}
+
+void server_info_cb(pa_context *c, const pa_server_info *i, void *userdata) {
+ char *default_output = (char *)userdata;
+
+ strncpy(default_output, i->default_sink_name, 1024);
+}
+
+static unsigned int detect_channels() {
+
+ pa_mainloop *pa_ml;
+ pa_mainloop_api *pa_mlapi;
+ pa_operation *pa_op;
+ pa_context *pa_ctx;
+
+ int state = 0;
+ int pa_ready = 0;
+
+ char default_output[1024];
+ unsigned int channels = 2;
+
+ pa_ml = pa_mainloop_new();
+ pa_mlapi = pa_mainloop_get_api(pa_ml);
+ pa_ctx = pa_context_new(pa_mlapi, "Godot");
+
+ int ret = pa_context_connect(pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL);
+ if (ret < 0) {
+ pa_context_unref(pa_ctx);
+ pa_mainloop_free(pa_ml);
+
+ return 2;
+ }
+
+ pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready);
+
+ // Wait until the pa server is ready
+ while (pa_ready == 0) {
+ pa_mainloop_iterate(pa_ml, 1, NULL);
+ }
+
+ // Check if there was an error connecting to the pa server
+ if (pa_ready == 2) {
+ pa_context_disconnect(pa_ctx);
+ pa_context_unref(pa_ctx);
+ pa_mainloop_free(pa_ml);
+
+ return 2;
+ }
+
+ // Get the default output device name
+ pa_op = pa_context_get_server_info(pa_ctx, &server_info_cb, (void *)default_output);
+ if (pa_op) {
+ while (pa_operation_get_state(pa_op) == PA_OPERATION_RUNNING) {
+ ret = pa_mainloop_iterate(pa_ml, 1, NULL);
+ if (ret < 0) {
+ ERR_PRINT("pa_mainloop_iterate error");
+ }
+ }
+
+ pa_operation_unref(pa_op);
+
+ // Now using the device name get the amount of channels
+ pa_op = pa_context_get_sink_info_by_name(pa_ctx, default_output, &sink_info_cb, (void *)&channels);
+ if (pa_op) {
+ while (pa_operation_get_state(pa_op) == PA_OPERATION_RUNNING) {
+ ret = pa_mainloop_iterate(pa_ml, 1, NULL);
+ if (ret < 0) {
+ ERR_PRINT("pa_mainloop_iterate error");
+ }
+ }
+
+ pa_operation_unref(pa_op);
+ } else {
+ ERR_PRINT("pa_context_get_sink_info_by_name error");
+ }
+ } else {
+ ERR_PRINT("pa_context_get_server_info error");
+ }
+
+ pa_context_disconnect(pa_ctx);
+ pa_context_unref(pa_ctx);
+ pa_mainloop_free(pa_ml);
+
+ return channels;
+}
+
Error AudioDriverPulseAudio::init() {
active = false;
thread_exited = false;
exit_thread = false;
- pcm_open = false;
- samples_in = NULL;
- samples_out = NULL;
mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE);
- speaker_mode = SPEAKER_MODE_STEREO;
- channels = 2;
+ channels = detect_channels();
+
+ switch (channels) {
+ case 2: // Stereo
+ case 4: // Surround 3.1
+ case 6: // Surround 5.1
+ case 8: // Surround 7.1
+ break;
+
+ default:
+ ERR_PRINTS("PulseAudio: Unsupported number of channels: " + itos(channels));
+ ERR_FAIL_V(ERR_CANT_OPEN);
+ break;
+ }
pa_sample_spec spec;
spec.format = PA_SAMPLE_S16LE;
@@ -59,7 +180,8 @@ Error AudioDriverPulseAudio::init() {
buffer_size = buffer_frames * channels;
if (OS::get_singleton()->is_stdout_verbose()) {
- print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
+ print_line("PulseAudio: detected " + itos(channels) + " channels");
+ print_line("PulseAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
}
pa_buffer_attr attr;
@@ -86,8 +208,8 @@ Error AudioDriverPulseAudio::init() {
ERR_FAIL_COND_V(pulse == NULL, ERR_CANT_OPEN);
}
- samples_in = memnew_arr(int32_t, buffer_size);
- samples_out = memnew_arr(int16_t, buffer_size);
+ samples_in.resize(buffer_size);
+ samples_out.resize(buffer_size);
mutex = Mutex::create();
thread = Thread::create(AudioDriverPulseAudio::thread_func, this);
@@ -119,7 +241,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
} else {
ad->lock();
- ad->audio_server_process(ad->buffer_frames, ad->samples_in);
+ ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptr());
ad->unlock();
@@ -132,7 +254,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
int error_code;
int byte_size = ad->buffer_size * sizeof(int16_t);
- if (pa_simple_write(ad->pulse, ad->samples_out, byte_size, &error_code) < 0) {
+ if (pa_simple_write(ad->pulse, ad->samples_out.ptr(), byte_size, &error_code) < 0) {
// can't recover here
fprintf(stderr, "PulseAudio failed and can't recover: %s\n", pa_strerror(error_code));
ad->active = false;
@@ -156,7 +278,7 @@ int AudioDriverPulseAudio::get_mix_rate() const {
AudioDriver::SpeakerMode AudioDriverPulseAudio::get_speaker_mode() const {
- return speaker_mode;
+ return get_speaker_mode_by_total_channels(channels);
}
void AudioDriverPulseAudio::lock() {
@@ -186,16 +308,6 @@ void AudioDriverPulseAudio::finish() {
pulse = NULL;
}
- if (samples_in) {
- memdelete_arr(samples_in);
- samples_in = NULL;
- }
-
- if (samples_out) {
- memdelete_arr(samples_out);
- samples_out = NULL;
- }
-
memdelete(thread);
if (mutex) {
memdelete(mutex);
@@ -207,11 +319,21 @@ void AudioDriverPulseAudio::finish() {
AudioDriverPulseAudio::AudioDriverPulseAudio() {
- samples_in = NULL;
- samples_out = NULL;
mutex = NULL;
thread = NULL;
pulse = NULL;
+
+ samples_in.clear();
+ samples_out.clear();
+
+ mix_rate = 0;
+ buffer_size = 0;
+ channels = 0;
+
+ active = false;
+ thread_exited = false;
+ exit_thread = false;
+
latency = 0;
buffer_frames = 0;
buffer_size = 0;
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h
index 9ae0b7e50c..3ede684496 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.h
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.h
@@ -43,14 +43,10 @@ class AudioDriverPulseAudio : public AudioDriver {
pa_simple *pulse;
- int32_t *samples_in;
- int16_t *samples_out;
-
- static void thread_func(void *p_udata);
+ Vector<int32_t> samples_in;
+ Vector<int16_t> samples_out;
unsigned int mix_rate;
- SpeakerMode speaker_mode;
-
unsigned int buffer_frames;
unsigned int buffer_size;
int channels;
@@ -58,10 +54,11 @@ class AudioDriverPulseAudio : public AudioDriver {
bool active;
bool thread_exited;
mutable bool exit_thread;
- bool pcm_open;
float latency;
+ static void thread_func(void *p_udata);
+
public:
const char *get_name() const {
return "PulseAudio";
diff --git a/drivers/rtaudio/audio_driver_rtaudio.cpp b/drivers/rtaudio/audio_driver_rtaudio.cpp
index ae5fdd28b6..a184c9e9cf 100644
--- a/drivers/rtaudio/audio_driver_rtaudio.cpp
+++ b/drivers/rtaudio/audio_driver_rtaudio.cpp
@@ -143,7 +143,7 @@ Error AudioDriverRtAudio::init() {
}
}
- return OK;
+ return active ? OK : ERR_UNAVAILABLE;
}
int AudioDriverRtAudio::get_mix_rate() const {
diff --git a/drivers/unix/SCsub b/drivers/unix/SCsub
index 5ced44dfda..c560e1289f 100644
--- a/drivers/unix/SCsub
+++ b/drivers/unix/SCsub
@@ -14,4 +14,6 @@ f.close()
env.add_source_files(env.drivers_sources, "*.cpp")
+env["check_c_headers"] = [ [ "mntent.h", "HAVE_MNTENT" ] ]
+
Export('env')
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index b85a63a44a..e7054e11a3 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -35,10 +35,17 @@
#include <sys/statvfs.h>
#endif
+#include "core/list.h"
#include "os/memory.h"
#include "print_string.h"
#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_MNTENT
+#include <mntent.h>
+#endif
DirAccess *DirAccessUnix::create_fs() {
@@ -176,13 +183,96 @@ void DirAccessUnix::list_dir_end() {
_cisdir = false;
}
+#if defined(HAVE_MNTENT) && defined(X11_ENABLED)
+static bool _filter_drive(struct mntent *mnt) {
+ // Ignore devices that don't point to /dev
+ if (strncmp(mnt->mnt_fsname, "/dev", 4) != 0) {
+ return false;
+ }
+
+ // Accept devices mounted at common locations
+ if (strncmp(mnt->mnt_dir, "/media", 6) == 0 ||
+ strncmp(mnt->mnt_dir, "/mnt", 4) == 0 ||
+ strncmp(mnt->mnt_dir, "/home", 5) == 0 ||
+ strncmp(mnt->mnt_dir, "/run/media", 10) == 0) {
+ return true;
+ }
+
+ // Ignore everything else
+ return false;
+}
+#endif
+
+static void _get_drives(List<String> *list) {
+
+#if defined(HAVE_MNTENT) && defined(X11_ENABLED)
+ // Check /etc/mtab for the list of mounted partitions
+ FILE *mtab = setmntent("/etc/mtab", "r");
+ if (mtab) {
+ struct mntent mnt;
+ char strings[4096];
+
+ while (getmntent_r(mtab, &mnt, strings, sizeof(strings))) {
+ if (mnt.mnt_dir != NULL && _filter_drive(&mnt)) {
+ // Avoid duplicates
+ if (!list->find(mnt.mnt_dir)) {
+ list->push_back(mnt.mnt_dir);
+ }
+ }
+ }
+
+ endmntent(mtab);
+ }
+#endif
+
+ // Add $HOME
+ const char *home = getenv("HOME");
+ if (home) {
+ // Only add if it's not a duplicate
+ if (!list->find(home)) {
+ list->push_back(home);
+ }
+
+ // Check $HOME/.config/gtk-3.0/bookmarks
+ char path[1024];
+ snprintf(path, 1024, "%s/.config/gtk-3.0/bookmarks", home);
+ FILE *fd = fopen(path, "r");
+ if (fd) {
+ char string[1024];
+ while (fgets(string, 1024, fd)) {
+ // Parse only file:// links
+ if (strncmp(string, "file://", 7) == 0) {
+ // Strip any unwanted edges on the strings and push_back if it's not a duplicate
+ String fpath = String(string + 7).strip_edges();
+ if (!list->find(fpath)) {
+ list->push_back(fpath);
+ }
+ }
+ }
+
+ fclose(fd);
+ }
+ }
+
+ list->sort();
+}
+
int DirAccessUnix::get_drive_count() {
- return 0;
+ List<String> list;
+ _get_drives(&list);
+
+ return list.size();
}
+
String DirAccessUnix::get_drive(int p_drive) {
- return "";
+ List<String> list;
+ _get_drives(&list);
+
+ ERR_FAIL_INDEX_V(p_drive, list.size(), "");
+
+ return list[p_drive];
}
Error DirAccessUnix::make_dir(String p_dir) {
@@ -221,37 +311,24 @@ Error DirAccessUnix::change_dir(String p_dir) {
if (prev_dir.parse_utf8(real_current_dir_name))
prev_dir = real_current_dir_name; //no utf8, maybe latin?
- //print_line("directory we are changing out of (prev_dir): " + prev_dir);
-
// try_dir is the directory we are trying to change into
String try_dir = "";
if (p_dir.is_rel_path()) {
String next_dir = current_dir + "/" + p_dir;
- //print_line("p_dir is relative: " + p_dir + " about to simplfy: " + next_dir);
next_dir = next_dir.simplify_path();
try_dir = next_dir;
} else {
try_dir = p_dir;
- //print_line("p_dir is absolute: " + p_dir);
- }
-
- // if try_dir is nothing, it is not changing directory so change it to a "." otherwise chdir will fail
- if (try_dir == "") {
- try_dir = ".";
}
- //print_line("directory we are changing in to (try_dir): " + try_dir);
-
bool worked = (chdir(try_dir.utf8().get_data()) == 0); // we can only give this utf8
if (!worked) {
- //print_line("directory does not exist");
return ERR_INVALID_PARAMETER;
}
// the directory exists, so set current_dir to try_dir
current_dir = try_dir;
chdir(prev_dir.utf8().get_data());
- //print_line("directory exists, setting current_dir to: " + current_dir);
return OK;
}
@@ -319,11 +396,16 @@ size_t DirAccessUnix::get_space_left() {
DirAccessUnix::DirAccessUnix() {
dir_stream = 0;
- current_dir = ".";
_cisdir = false;
/* determine drive count */
+ // set current directory to an absolute path of the current directory
+ char real_current_dir_name[2048];
+ getcwd(real_current_dir_name, 2048);
+ if (current_dir.parse_utf8(real_current_dir_name))
+ current_dir = real_current_dir_name;
+
change_dir(current_dir);
}
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index 80565c5b02..649f874cf4 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -168,7 +168,7 @@ void FileAccessUnix::seek_end(int64_t p_position) {
check_errors();
}
-size_t FileAccessUnix::get_pos() const {
+size_t FileAccessUnix::get_position() const {
ERR_FAIL_COND_V(!f, 0);
@@ -274,6 +274,15 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
};
}
+Error FileAccessUnix::_chmod(const String &p_path, int p_mod) {
+ int err = chmod(p_path.utf8().get_data(), p_mod);
+ if (!err) {
+ return OK;
+ }
+
+ return FAILED;
+}
+
FileAccess *FileAccessUnix::create_libc() {
return memnew(FileAccessUnix);
diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h
index 6e5110431f..e2848e4128 100644
--- a/drivers/unix/file_access_unix.h
+++ b/drivers/unix/file_access_unix.h
@@ -62,7 +62,7 @@ public:
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
- virtual size_t get_pos() const; ///< get position in the file
+ virtual size_t get_position() 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
@@ -78,6 +78,8 @@ public:
virtual uint64_t _get_modified_time(const String &p_file);
+ virtual Error _chmod(const String &p_path, int p_mod);
+
FileAccessUnix();
virtual ~FileAccessUnix();
};
diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h
index 3fc0144294..0995e5236f 100644
--- a/drivers/unix/socket_helpers.h
+++ b/drivers/unix/socket_helpers.h
@@ -64,7 +64,6 @@ static size_t _set_sockaddr(struct sockaddr_storage *p_addr, const IP_Address &p
// IPv4 socket with IPv6 address
ERR_FAIL_COND_V(!p_ip.is_ipv4(), 0);
- uint32_t ipv4 = *((uint32_t *)p_ip.get_ipv4());
struct sockaddr_in *addr4 = (struct sockaddr_in *)p_addr;
addr4->sin_family = AF_INET;
addr4->sin_port = htons(p_port); // short, network byte order
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index 29d1e5deed..eb86491dec 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -67,12 +67,13 @@ Error AudioDriverWASAPI::init_device() {
switch (channels) {
case 2: // Stereo
+ case 4: // Surround 3.1
case 6: // Surround 5.1
case 8: // Surround 7.1
break;
default:
- ERR_PRINT("WASAPI: Unsupported number of channels");
+ ERR_PRINTS("WASAPI: Unsupported number of channels: " + itos(channels));
ERR_FAIL_V(ERR_CANT_OPEN);
break;
}
@@ -119,7 +120,8 @@ Error AudioDriverWASAPI::init_device() {
samples_in.resize(buffer_size);
if (OS::get_singleton()->is_stdout_verbose()) {
- print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
+ print_line("WASAPI: detected " + itos(channels) + " channels");
+ print_line("WASAPI: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
}
return OK;
@@ -185,7 +187,7 @@ int AudioDriverWASAPI::get_mix_rate() const {
AudioDriver::SpeakerMode AudioDriverWASAPI::get_speaker_mode() const {
- return SPEAKER_MODE_STEREO;
+ return get_speaker_mode_by_total_channels(channels);
}
void AudioDriverWASAPI::thread_func(void *p_udata) {
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index 30c8332fa3..d128b58244 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -156,10 +156,11 @@ void FileAccessWindows::seek_end(int64_t p_position) {
if (fseek(f, p_position, SEEK_END))
check_errors();
}
-size_t FileAccessWindows::get_pos() const {
+size_t FileAccessWindows::get_position() const {
size_t aux_position = 0;
- if (!(aux_position = ftell(f))) {
+ aux_position = ftell(f);
+ if (!aux_position) {
check_errors();
};
return aux_position;
@@ -168,9 +169,9 @@ size_t FileAccessWindows::get_len() const {
ERR_FAIL_COND_V(!f, 0);
- size_t pos = get_pos();
+ size_t pos = get_position();
fseek(f, 0, SEEK_END);
- int size = get_pos();
+ int size = get_position();
fseek(f, pos, SEEK_SET);
return size;
diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h
index 6956e7855a..15cbdca739 100644
--- a/drivers/windows/file_access_windows.h
+++ b/drivers/windows/file_access_windows.h
@@ -54,7 +54,7 @@ public:
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
- virtual size_t get_pos() const; ///< get position in the file
+ virtual size_t get_position() 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